1def binary_search(a, target):2 low, high = 0, len(a) - 13 while low <= high:4 mid = (low + high) // 25 if a[mid] == target:6 return mid7 elif a[mid] < target:8 low = mid + 19 else:10 high = mid - 111 return -1target42comparisonsbisect03172113154195246287338389421047115112561361146715729ilowhighmid
Memory boxes: a sorted list, index above, value below; faded boxes are ruled outCode card: binary search in Python; the highlighted line is the one runningMarkers: i (linear search), low, mid and high (binary search)Target, comparisons counter and Python's bisect moduleThe row is a sorted list of 16 numbers; the small number on each box is its index. A linear search sweeps the marker i from index 0 and needs 10 comparisons to reach 42 at index 9. Binary search keeps low and high around the part still in play and probes mid = (low + high) // 2: a[7] = 33 is too small, so low = 8; a[11] = 51 is too big, so high = 10; a[9] is 42. Three comparisons; each one throws away about half of what was left. The drawing counts one comparison per item looked at. The code tests a[mid] == target and then a[mid] < target, so in Python terms that can be two tests per item; the count still grows as log n.

Linear search

  1. Linear search starts at the front and checks each item in turn until it finds the target. Finding 42 here takes 10 comparisons. On a list of n items it may need all n, so it is O(n).

Binary search

Speed and pitfalls

Try it in the Python prompt

;; step 1/10 · Linear search: one by one
>>> def linear_search(a, target):
...     for i in range(len(a)):
...         if a[i] == target:
...             return i
...     return -1
...
>>> a = [3, 7, 11, 15, 19, 24, 28, 33, 38, 42, 47, 51, 56, 61, 67, 72]
>>> linear_search(a, 42)   # looks at a[0], a[1], ... a[9]
9
>>> 42 in a                # also a linear search
True

The drawing counts one comparison per item looked at. The code tests a[mid] == target and then a[mid] < target, so in Python terms that can be two tests per item; the count still grows as log n. This binary search looks at no more than floor(log2 n) + 1 items, whether the target is there or not. For n = 16 that is 5; for n = 1,000,000 it is 20, because 2^19 = 524,288 is not more than a million but 2^20 = 1,048,576 is.