Binary Search
The idea
Think of finding a word in a dictionary. Nobody reads page 1, then page 2, then page 3. You open it near the middle, see whether your word comes earlier or later, and instantly ignore half the book. A few splits later you are on the right page.
The problem
Finding a value by checking every item works, but it is painfully slow on big lists. If the list is SORTED, there is a far smarter way: look in the middle, decide which half the target must be in, and throw the other half away. Repeat. Every look removes half of the remaining items.
Why it's slow
Slow? Quite the opposite — this is the fast one. Our demo found the target in ONE comparison where linear search needed five. Each comparison halves what is left: 1,000 items need about 10 looks, a million about 20, a billion about 30. That growth is O(log n). The price of admission: the list must already be sorted.
Pseudocode
-
make sure the list is sorted first
Explain this line
Binary search is USELESS on an unsorted list — this rule is sacred.
-
put one finger at each end: low and high
Explain this line
low and high fence off where the target can still hide.
-
look at the middle position between them
Explain this line
The midpoint between the fingers is always the next guess.
-
compare the middle item with the target
Explain this line
One comparison per guess — watch how few we need.
-
hit? done. Too small? go right. Too big? go left
Explain this line
Each wrong guess still throws away half of the possibilities.
Complexity
| Best | Average | Worst | Space |
|---|---|---|---|
| O(1) | O(log n) | O(log n) | O(1) |
The classic trade: pay once to keep data sorted, then every search is astonishingly cheap. This is why databases keep indexes.
Code
python
def binary_search(a, target): # a must be sorted
low, high = 0, len(a) - 1
while low <= high:
mid = (low + high) // 2
if a[mid] == target:
return mid
if a[mid] < target:
low = mid + 1
else:
high = mid - 1
return -1
java
int binarySearch(int[] a, int target) { // a must be sorted
int low = 0, high = a.length - 1;
while (low <= high) {
int mid = low + (high - low) / 2;
if (a[mid] == target) return mid;
if (a[mid] < target) low = mid + 1;
else high = mid - 1;
}
return -1;
}
cpp
int binarySearch(const std::vector<int>& a, int target) {
int low = 0, high = static_cast<int>(a.size()) - 1;
while (low <= high) {
int mid = low + (high - low) / 2;
if (a[mid] == target) return mid;
if (a[mid] < target) low = mid + 1;
else high = mid - 1;
}
return -1;
}
javascript
function binarySearch(a, target) { // a must be sorted
let low = 0, high = a.length - 1;
while (low <= high) {
const mid = (low + high) >> 1;
if (a[mid] === target) return mid;
if (a[mid] < target) low = mid + 1;
else high = mid - 1;
}
return -1;
}
dart
int binarySearch(List<int> a, int target) { // a must be sorted
var low = 0, high = a.length - 1;
while (low <= high) {
final mid = (low + high) ~/ 2;
if (a[mid] == target) return mid;
if (a[mid] < target) {
low = mid + 1;
} else {
high = mid - 1;
}
}
return -1;
}