|
40 | 40 | \text{Output: } \text{not found} |
41 | 41 | $$ |
42 | 42 |
|
43 | | -**How it works** |
| 43 | +**How Linear Search Works** |
| 44 | + |
| 45 | +We start at index `0`, compare the value with the target, and keep moving right until we either **find it** or reach the **end**. |
44 | 46 |
|
45 | | -Start at index 0, compare, move right; stop on first equal or after the last element. |
| 47 | +Target **5** in `[7, 3, 5, 2, 9]` |
46 | 48 |
|
47 | 49 | ``` |
48 | | -Indexes: 0 1 2 3 4 |
49 | | -List: [ 7 ][ 3 ][ 5 ][ 2 ][ 9 ] |
| 50 | +Indexes: 0 1 2 3 4 |
| 51 | +List: [7] [3] [5] [2] [9] |
50 | 52 | Target: 5 |
| 53 | +``` |
51 | 54 |
|
52 | | -Pass 1: pointer at 0 → compare 7 vs 5 → no |
53 | | - v |
54 | | -Indexes: 0 1 2 3 4 |
55 | | - | |
56 | | -List: 7 3 5 2 9 |
| 55 | +*Step 1:* pointer at index 0 |
57 | 56 |
|
58 | | -Pass 2: pointer at 1 → compare 3 vs 5 → no |
59 | | - v |
60 | | -Indexes: 0 1 2 3 4 |
61 | | - | |
62 | | -List: 7 3 5 2 9 |
| 57 | +``` |
| 58 | +| |
| 59 | +v |
| 60 | +7 3 5 2 9 |
63 | 61 |
|
64 | | -Pass 3: pointer at 2 → compare 5 vs 5 → YES → return 2 |
65 | | - v |
66 | | -Indexes: 0 1 2 3 4 |
67 | | - | |
68 | | -List: 7 3 5 2 9 |
| 62 | +→ compare 7 vs 5 → no |
69 | 63 | ``` |
70 | 64 |
|
71 | | -**Worst case (not found):** you compare every element and then stop. |
| 65 | +*Step 2:* pointer moves to index 1 |
| 66 | + |
| 67 | +``` |
| 68 | + | |
| 69 | + v |
| 70 | +7 3 5 2 9 |
72 | 71 |
|
| 72 | +→ compare 3 vs 5 → no |
73 | 73 | ``` |
74 | | -Indexes: 0 1 2 |
75 | | -List: [ 1 ][ 2 ][ 3 ] |
| 74 | + |
| 75 | +*Step 3:* pointer moves to index 2 |
| 76 | + |
| 77 | +``` |
| 78 | + | |
| 79 | + v |
| 80 | +7 3 5 2 9 |
| 81 | +
|
| 82 | +→ compare 5 vs 5 → YES ✅ → return index 2 |
| 83 | +``` |
| 84 | + |
| 85 | +**Worst Case (Not Found)** |
| 86 | + |
| 87 | +Target **9** in `[1, 2, 3]` |
| 88 | + |
| 89 | +``` |
| 90 | +Indexes: 0 1 2 |
| 91 | +List: [1] [2] [3] |
76 | 92 | Target: 9 |
| 93 | +``` |
77 | 94 |
|
78 | | -Checks: (1≠9) → (2≠9) → (3≠9) → end → not found |
| 95 | +Checks: |
| 96 | + |
| 97 | +``` |
| 98 | +→ 1 ≠ 9 |
| 99 | +→ 2 ≠ 9 |
| 100 | +→ 3 ≠ 9 |
| 101 | +→ end |
| 102 | +→ not found ❌ |
79 | 103 | ``` |
80 | 104 |
|
81 | 105 | * Works on any list; no sorting or structure required. |
|
116 | 140 |
|
117 | 141 | Put the target at one extra slot at the end so the loop is guaranteed to stop on a match; afterward, check whether the match was inside the original range. |
118 | 142 |
|
| 143 | +Target **11** not in the list |
| 144 | + |
119 | 145 | ``` |
120 | | -Original length n = 5 |
121 | | -Before: [ 4 ][ 9 ][ 1 ][ 7 ][ 6 ] |
| 146 | +Original list (n=5): |
| 147 | +[ 4 ][ 9 ][ 1 ][ 7 ][ 6 ] |
122 | 148 | Target: 11 |
| 149 | +``` |
123 | 150 |
|
124 | 151 | Add sentinel (extra slot): |
125 | | - [ 4 ][ 9 ][ 1 ][ 7 ][ 6 ][ 11 ] |
126 | | -Indexes: 0 1 2 3 4 5 ← sentinel position |
127 | 152 |
|
128 | | -Scan left→right until you see 11: |
| 153 | +``` |
| 154 | +[ 4 ][ 9 ][ 1 ][ 7 ][ 6 ][ 11 ] |
| 155 | + 0 1 2 3 4 5 ← sentinel |
| 156 | +``` |
129 | 157 |
|
130 | | -Step 1: 4 ≠ 11 |
131 | | - ^ |
132 | | -Step 2: 9 ≠ 11 |
133 | | - ^ |
134 | | -Step 3: 1 ≠ 11 |
135 | | - ^ |
136 | | -Step 4: 7 ≠ 11 |
137 | | - ^ |
138 | | -Step 5: 6 ≠ 11 |
139 | | - ^ |
140 | | -Step 6: 11 (match at index 5, which is the sentinel) |
| 158 | +Scan step by step: |
141 | 159 |
|
142 | | -Because the first match is at index 5 (the sentinel position), the target was not in the original indexes 0..4 → report “not found”. |
143 | 160 | ``` |
| 161 | +4 ≠ 11 → pointer at 0 |
| 162 | +9 ≠ 11 → pointer at 1 |
| 163 | +1 ≠ 11 → pointer at 2 |
| 164 | +7 ≠ 11 → pointer at 3 |
| 165 | +6 ≠ 11 → pointer at 4 |
| 166 | +11 = 11 → pointer at 5 (sentinel) |
| 167 | +``` |
| 168 | + |
| 169 | +Therefore, **not found** in original list. |
144 | 170 |
|
145 | | -**When the target exists inside the list:** |
| 171 | +Target **6** inside the list |
146 | 172 |
|
147 | 173 | ``` |
148 | | -List: [ 12 ][ 8 ][ 6 ][ 15 ] n = 4 |
| 174 | +Original list (n=4): |
| 175 | +[ 12 ][ 8 ][ 6 ][ 15 ] |
149 | 176 | Target: 6 |
150 | | -With sentinel: [ 12 ][ 8 ][ 6 ][ 15 ][ 6 ] |
| 177 | +``` |
| 178 | + |
| 179 | +Add sentinel: |
| 180 | + |
| 181 | +``` |
| 182 | +[ 12 ][ 8 ][ 6 ][ 15 ][ 6 ] |
| 183 | + 0 1 2 3 4 |
| 184 | +``` |
| 185 | + |
| 186 | +Scan: |
151 | 187 |
|
152 | | -Scan: 12≠6 → 8≠6 → 6=6 (index 2 < n) → real match at 2 |
| 188 | +``` |
| 189 | +12 ≠ 6 → index 0 |
| 190 | + 8 ≠ 6 → index 1 |
| 191 | + 6 = 6 → index 2 ✅ |
153 | 192 | ``` |
154 | 193 |
|
155 | 194 | * Removes the per-iteration “have we reached the end?” check; the sentinel guarantees termination. |
|
198 | 237 | \text{Output: } \text{not found} |
199 | 238 | $$ |
200 | 239 |
|
201 | | - |
202 | 240 | **How it works** |
203 | 241 |
|
| 242 | +We repeatedly check the **middle** element, and then discard half the list based on comparison. |
| 243 | + |
| 244 | +Find **16** in: |
| 245 | + |
| 246 | +``` |
| 247 | +A = [ 2 ][ 5 ][ 8 ][ 12 ][ 16 ][ 23 ][ 38 ] |
| 248 | +i = 0 1 2 3 4 5 6 |
204 | 249 | ``` |
205 | | -Sorted A: [ 2 ][ 5 ][ 8 ][12 ][16 ][23 ][38 ] |
206 | | -Indexes: 0 1 2 3 4 5 6 |
207 | | -Target: 16 |
208 | 250 |
|
209 | | -1) low=0, high=6 → mid=(0+6)//2=3 |
210 | | - A[3]=12 < 16 → discard left half up to mid, keep [mid+1..high] |
211 | | - [ 2 ][ 5 ][ 8 ] |[12 ]| [16 ][23 ][38 ] |
212 | | - low=4 high=6 |
| 251 | +*Step 1* |
213 | 252 |
|
214 | | -2) low=4, high=6 → mid=(4+6)//2=5 |
215 | | - A[5]=23 > 16 → discard right half after mid, keep [low..mid-1] |
216 | | - [16 ][23 ]|[38 ] |
217 | | - low=4 high=4 |
| 253 | +``` |
| 254 | +low = 0, high = 6 |
| 255 | +mid = (0+6)//2 = 3 |
| 256 | +A[3] = 12 < 16 → target is to the RIGHT → new low = mid + 1 = 4 |
| 257 | +
|
| 258 | +A = [ 2 ][ 5 ][ 8 ][ 12 ][ 16 ][ 23 ][ 38 ] |
| 259 | +i = 0 1 2 3 4 5 6 |
| 260 | + ↑L ↑M ↑H |
| 261 | + 0 3 6 |
| 262 | +Active range: indices 0..6 |
| 263 | +``` |
218 | 264 |
|
219 | | -3) low=4, high=4 → mid=4 |
220 | | - A[4]=16 = target → FOUND at index 4 |
| 265 | +*Step 2* |
| 266 | + |
| 267 | +``` |
| 268 | +low = 4, high = 6 |
| 269 | +mid = (4+6)//2 = 5 |
| 270 | +A[5] = 23 > 16 → target is to the LEFT → new high = mid - 1 = 4 |
| 271 | +
|
| 272 | +A = [ 2 ][ 5 ][ 8 ][ 12 ][ 16 ][ 23 ][ 38 ] |
| 273 | +i = 0 1 2 3 4 5 6 |
| 274 | + ↑L ↑M ↑H |
| 275 | + 4 5 6 |
| 276 | +Active range: indices 4..6 |
221 | 277 | ``` |
222 | 278 |
|
| 279 | +*Step 3* |
| 280 | + |
| 281 | +``` |
| 282 | +low = 4, high = 4 |
| 283 | +mid = 4 |
| 284 | +A[4] = 16 == target ✅ |
| 285 | +
|
| 286 | +A = [ 2 ][ 5 ][ 8 ][ 12 ][ 16 ][ 23 ][ 38 ] |
| 287 | +i = 0 1 2 3 4 5 6 |
| 288 | + ↑LMH |
| 289 | + 4 |
| 290 | +Active range: indices 4..4 |
| 291 | +``` |
| 292 | + |
| 293 | +FOUND at index 4 |
| 294 | + |
223 | 295 | * Requires a sorted array (assume ascending here). |
224 | 296 | * Time: O(log n); Space: O(1) iterative. |
225 | 297 | * Returns any one matching index by default; “first/last occurrence” is a small, common refinement. |
|
253 | 325 |
|
254 | 326 | **How it works** |
255 | 327 |
|
| 328 | +We divide the array into **three parts** using two midpoints `m1` and `m2`. |
| 329 | + |
| 330 | +* If `target < A[m1]` → search $[low .. m1-1]$ |
| 331 | +* Else if `target > A[m2]` → search $[m2+1 .. high]$ |
| 332 | +* Else → search $[m1+1 .. m2-1]$ |
| 333 | + |
256 | 334 | ``` |
257 | | -Sorted A: [ 1 ][ 4 ][ 7 ][ 9 ][12 ][15 ] |
258 | | -Indexes: 0 1 2 3 4 5 |
| 335 | +A = [ 1 ][ 4 ][ 7 ][ 9 ][ 12 ][ 15 ] |
| 336 | +i = 0 1 2 3 4 5 |
259 | 337 | Target: 9 |
| 338 | +``` |
260 | 339 |
|
261 | | -1) low=0, high=5 |
262 | | - m1 = low + (high-low)//3 = 0 + 5//3 = 1 |
263 | | - m2 = high - (high-low)//3 = 5 - 5//3 = 3 |
| 340 | +*Step 1* |
264 | 341 |
|
265 | | - Compare A[m1]=4, A[m2]=9 with target=9: |
| 342 | +``` |
| 343 | +low = 0, high = 5 |
| 344 | +
|
| 345 | +m1 = low + (high - low)//3 = 0 + (5)//3 = 1 |
| 346 | +m2 = high - (high - low)//3 = 5 - (5)//3 = 3 |
266 | 347 |
|
267 | | - A[m2]=9 = target → FOUND at index 3 |
| 348 | +A[m1] = 4 |
| 349 | +A[m2] = 9 |
268 | 350 |
|
269 | | -(If no immediate match:) |
270 | | -- If target < A[m1], keep [low..m1-1] |
271 | | -- Else if target > A[m2], keep [m2+1..high] |
272 | | -- Else keep [m1+1..m2-1] and repeat |
| 351 | +A = [ 1 ][ 4 ][ 7 ][ 9 ][ 12 ][ 15 ] |
| 352 | +i = 0 1 2 3 4 5 |
| 353 | + ↑L ↑m1 ↑m2 ↑H |
| 354 | + 0 1 3 5 |
273 | 355 | ``` |
274 | 356 |
|
| 357 | +FOUND at index 3 |
| 358 | + |
275 | 359 | * Also assumes a sorted array. |
276 | 360 | * For discrete sorted arrays, it does **not** beat binary search asymptotically; it performs more comparisons per step. |
277 | 361 | * Most valuable for searching the extremum of a **unimodal function** on a continuous domain; for arrays, prefer binary search. |
|
304 | 388 |
|
305 | 389 | **How it works** |
306 | 390 |
|
| 391 | +Perfect — that’s a **jump search trace**. Let me reformat and polish it so the steps are crystal clear and the “jump + linear scan” pattern pops visually: |
| 392 | + |
| 393 | +We’re applying **jump search** to find $25$ in |
| 394 | + |
| 395 | +$$ |
| 396 | +A = [1, 4, 9, 16, 25, 36, 49] |
| 397 | +$$ |
| 398 | + |
| 399 | +with $n=7$, block size $\approx \sqrt{7} \approx 2$, so **jump=2**. |
| 400 | + |
| 401 | +We probe every 2nd index: |
| 402 | + |
| 403 | +* probe = 0 → $A[0] = 1 < 25$ → jump to 2 |
| 404 | +* probe = 2 → $A[2] = 9 < 25$ → jump to 4 |
| 405 | +* probe = 4 → $A[4] = 25 \geq 25$ → stop |
| 406 | + |
| 407 | +So target is in block $(2..4]$. |
| 408 | + |
307 | 409 | ``` |
308 | | -Sorted A: [ 1 ][ 4 ][ 9 ][16 ][25 ][36 ][49 ] |
309 | | -Indexes: 0 1 2 3 4 5 6 |
310 | | -Target: 25 |
311 | | -Choose block size ≈ √n → here n=7 → jump=2 |
| 410 | +[ 1 ][ 4 ] | [ 9 ][16 ] | [25 ][36 ] | [49 ] |
| 411 | + ^ ^ ^ ^ |
| 412 | + probe=0 probe=2 probe=4 probe=6 |
| 413 | +``` |
| 414 | + |
| 415 | +Linear Scan in block (indexes 3..4) |
312 | 416 |
|
313 | | -Jumps (probe at 0,2,4,6 until A[probe] ≥ target): |
314 | | -- probe=0 → A[0]=1 (<25) → next probe=2 |
315 | | -- probe=2 → A[2]=9 (<25) → next probe=4 |
316 | | -- probe=4 → A[4]=25 (≥25) → target must be in block (2..4] |
| 417 | +* i = 3 → $A[3] = 16 < 25$ |
| 418 | +* i = 4 → $A[4] = 25 = 25$ ✅ FOUND |
317 | 419 |
|
318 | | -Linear scan inside last block (indexes 3..4): |
319 | | -- i=3 → A[3]=16 (<25) |
320 | | -- i=4 → A[4]=25 (=) FOUND at index 4 |
321 | 420 | ``` |
| 421 | +Block [16 ][25 ] |
| 422 | + ^ ^ |
| 423 | + i=3 i=4 (found!) |
| 424 | +``` |
| 425 | + |
| 426 | +The element $25$ is found at **index 4**. |
322 | 427 |
|
323 | 428 | * Works on sorted arrays; pick jump ≈ √n for good balance. |
324 | 429 | * Time: O(√n) comparisons on average; Space: O(1). |
|
0 commit comments