Binary Search
How halving wins — log time made visible.
Prerequisites:Conditions & Booleans
Story — guess my number
I'm thinking of a number between 1 and 100. You guess; I tell you higher, lower, or got it. What's your strategy?
Smart players don't guess 1, then 2, then 3 — that's a linear search and it could take 100 guesses. They guess 50, slicing the range in half. Then 25 or 75. Then half again. In seven guesses, you can pinpoint any number from 1 to 100. That is binary search.
Halver says
See it — half goes dark each step
Pick a target. Press Step. Watch which half gets crossed out — those values can't possibly hold your target, so the algorithm forgets about them entirely.
- 03
- 17
- 211
- 318
- 424
- 531
- 642
- 755
- 863
- 978
- 1084
- 1191
- 1299
Searching 13 items for 42. Press Step to compare with the middle.
low=0 · high=12 · steps=0
✎ Sharpen your pencil
After watching a few searches, write one sentence describing what "low" and "high" represent — without using the word "index".
Halver says
Try it — count the steps
Exercise. Imagine a sorted list of 1,000,000 entries. Without using a calculator, what's the maximum number of comparisons binary search needs?
Reveal answer
Each step halves the list, so the question is: how many times can you halve a million before you reach 1? 1,000,000 → 500,000 → 250,000 → … 2 → 1 takes about 20 halvings. That's log₂(1,000,000) ≈ 20. Twenty comparisons to find a needle in a million-item haystack.
Code it — five languages, one halving
The shape is identical everywhere: two pointers (low and high), a middle, a three-way comparison, and shrink one side. The only per-language wrinkle is integer overflow when adding low and high — Java and C++ use low + (high - low) / 2 to stay safe.
def binary_search(arr, target):
low, high = 0, len(arr) - 1
while low <= high:
mid = (low + high) // 2
if arr[mid] == target:
return mid
elif arr[mid] < target:
low = mid + 1
else:
high = mid - 1
return -1Walk through it line by line
1arr = [3, 7, 11, 18, 24, 31, 42, 55, 63, 78, 84, 91, 99]2target = 423low, high = 0, 124mid = (low + high) // 2 # 65arr[mid] # 42 — found at index 6
Halver says
Quiz it — make it stick
No Dumb Questions
Real questions other learners asked on this page.
What if the array has duplicates?
Plain binary search returns *some* matching index, not necessarily the first or last. If you need leftmost or rightmost, you tweak the comparison: keep moving "high = mid" (not mid - 1) when you find a match, and keep going until low == high. That gives you the first occurrence.When is linear search actually better?
When the array is unsorted (binary search just won't work), when it's tiny (10 items — overhead beats halving), or when you're going to scan everything anyway. Binary search wins on big sorted lookups; that's its niche.Why use `(low + high) / 2` and not `(high - low) / 2`?
Because we want the midpoint — halfway between low and high, not half the distance. The version `low + (high - low) / 2` is mathematically the same as `(low + high) / 2`, but it avoids overflowing when low + high exceeds the integer maximum (a real bug Joshua Bloch wrote about for Java's Arrays.binarySearch).