Given a sorted array $A$ of $n$ elements and a target value, find the index of the target (or determine it is not present).
KEY TAKEAWAY: Binary search works by repeatedly halving the search space. It requires the input to be sorted. Time complexity: $O(\log n)$.
ALGORITHM BinarySearch(A, target)
low ← 0
high ← length(A) - 1
while low <= high do
mid ← (low + high) / 2 // integer division
if A[mid] = target then
return mid
else if A[mid] < target then
low ← mid + 1 // target is in right half
else
high ← mid - 1 // target is in left half
end if
end while
return -1 // target not found
Array: $A = [2, 5, 8, 12, 16, 23, 38, 56, 72, 91]$, Target: 23
| Step | low | high | mid | A[mid] | Action |
|---|---|---|---|---|---|
| 1 | 0 | 9 | 4 | 16 | 23 > 16 → low = 5 |
| 2 | 5 | 9 | 7 | 56 | 23 < 56 → high = 6 |
| 3 | 5 | 6 | 5 | 23 | Found at index 5 ✓ |
Recurrence: $T(n) = T(n/2) + O(1)$
Comparison to linear search:
| $n$ | Linear search | Binary search |
|---|---|---|
| 100 | 100 | 7 |
| 10,000 | 10,000 | 14 |
| $10^9$ | $10^9$ | 30 |
Binary search is an example of the Divide and Conquer pattern:
1. Divide: Find the midpoint; compare target with middle element
2. Eliminate: Discard the half that cannot contain the target
3. Recurse: Search remaining half
def binary_search(A, target, low, high):
if low > high:
return -1
mid = (low + high) // 2
if A[mid] == target:
return mid
elif A[mid] < target:
return binary_search(A, target, mid + 1, high)
else:
return binary_search(A, target, low, mid - 1)
Loop invariant: If the target is present, it lies in $A[low..high]$.
- Initially: $A[0..n-1]$ — the entire array
- Maintained: Each iteration correctly narrows the range based on the comparison
- Termination: low > high means target is absent
EXAM TIP: Binary search requires a sorted input — always state this precondition. If asked to trace, show the values of
low,high, andmidat each step.