edubun 한국어

Searching: linear and binary search

To find one name in a sorted list of a million, binary search never needs more than 20 checks.

Looking for one value

Searching is the problem of finding where a value is in a collection, or learning that it is not there. Your phone does it when you type a contact's name, a shop does it when it checks whether an item is in stock, and a spell checker does it for every word you type. The input is a list and a target value. The output is the position of the target, or a sign such as -1 meaning "not found".

Linear search: one at a time

The plainest method is to start at the left and check each value in turn until you find the target or run out of list. This is linear search. It works on any list, sorted or not. Its cost depends on luck: if the target is first, one check is enough; if it is last or missing, you check every value. For a list of n values the worst case is n checks. A list twice as long can take twice as many checks, which is where the name "linear" comes from: the work grows in a straight line with the size.

function linearSearch(list, target) {
  for (let i = 0; i < list.length; i++) {
    if (list[i] === target) return i;  // found it
  }
  return -1;                             // checked everything
}

Binary search: halve what is left

If the list is sorted, you can do much better. Think of the number guessing game: someone picks a number from 1 to 100 and answers only "higher" or "lower". A sensible player guesses 50 first. Whatever the answer, half the possibilities are gone. The next guess is the middle of what is left, and so on. Binary search does exactly this with a sorted list. It keeps two markers, lo and hi, around the part where the target could still be. It checks the middle value. If that is the target, it is done. If the middle value is smaller than the target, everything to its left is smaller too, so lo moves past the middle. If it is larger, hi moves before the middle. When lo passes hi, nothing is left and the target is not in the list.

function binarySearch(list, target) {
  let lo = 0, hi = list.length - 1;
  while (lo <= hi) {
    const mid = Math.floor((lo + hi) / 2);
    if (list[mid] === target) return mid;
    if (list[mid] < target) lo = mid + 1;  // target is to the right
    else hi = mid - 1;                     // target is to the left
  }
  return -1;
}
Loading

Drag to turn. Scroll or pinch to zoom.

A sorted list of 31 numbers. Pick a target, then step through binary search and linear search and compare the number of checks.

How many checks?

Each check of binary search at least halves the part that is left. Starting from n values, after one check at most about n/2 remain, after two about n/4, and so on until one value is left. The number of halvings needed to get from n down to 1 is the base 2 logarithm of n, written log₂ n. Counting the final check as well, binary search needs at most ⌊log₂ n⌋ + 1 checks, where ⌊ ⌋ means rounding down. For 100 values that is 7 checks, which is why the guessing game can always be won in 7 guesses. For 1,000 values it is 10, for a million 20, and for a billion 30.

List size nLinear search, worst caseBinary search, worst case
773
1001007
1,0001,00010
1,000,0001,000,00020
1,000,000,0001,000,000,00030

The catch: the list must be sorted

Binary search only works because, in a sorted list, one comparison tells you which side the target must be on. On an unsorted list the middle value tells you nothing about its neighbours, so you are back to linear search. Sorting takes work of its own (the next two units are about that), so the choice depends on use. If you search a list once, a linear search may be cheapest. If you search the same list thousands of times, sorting it once and then using binary search pays off quickly. This trade between preparing data and answering questions about it runs through the whole subject.

A classic slip in binary search is the update step. Writing lo = mid instead of lo = mid + 1 can make the loop run forever when two values are left, because mid never changes. The middle value has already been checked, so it can be left out of the next range.
linear searchCheck values one by one from the start
binary searchCheck the middle of a sorted range and drop the half that cannot hold the target
worst caseThe input that makes the algorithm do the most work
log₂ nHow many times n can be halved before reaching 1
lo and hiThe two ends of the range where the target could still be
-1A common return value meaning "not found"
  1. At most how many checks does binary search need for a sorted list of 1,000 values?
  2. At most how many checks does linear search need for a list of 1,000 values?
  3. Binary search needs the list to be
    • sorted
    • short
    • made of whole numbers
    • without repeated values
  4. In the list [2, 5, 8, 12, 16, 23, 38, 56, 72, 91], how many checks does binary search make to find 23?
  5. In the same list, how many checks does linear search make to find 23?
  6. Binary search checks a middle value 40 while looking for 25. What happens next?
    • hi moves to just before the middle
    • lo moves to just after the middle
    • the search stops: 25 is missing
    • it checks the next value to the right
  7. You may guess a number from 1 to 100 and are told "higher" or "lower". With the best strategy, how many guesses are always enough?
  8. A list doubles in size. What happens to the worst-case number of binary search checks?
    • It doubles
    • It grows by about one
    • It stays exactly the same
    • It is squared
  9. You will look up a single value in an unsorted list once. Which is cheaper?
    • Linear search
    • Sort the list, then binary search
  10. Why can lo = mid (instead of mid + 1) make binary search loop forever?
    • With two values left, mid can stay the same every round
    • mid becomes negative
    • JavaScript does not allow it
    • The list gets longer
  11. At most how many checks does binary search need for 1,000,000 values?
Key points
  • Linear search checks one value at a time: up to n checks.
  • Binary search halves the range that is left: up to ⌊log₂ n⌋ + 1 checks.
  • Binary search only works on a sorted list.
  • A million values: 20 checks at most.
  • Update with mid + 1 and mid − 1 so the range always shrinks.