Binary Search

In computer science, binary search is a search algorithm for searching a set of sorted data for a particular value. A binary search requires random access to the data being searched. In its simplest form, binary search assumes the data is sorted (usually by a sort algorithm) and takes advantage of that characteristic.

Examples

An example of binary search in action is a simple guessing game in which a player has to guess a positive integer selected by another player between 1 and N, using only questions answered with yes or no. Supposing N is 16 and the number 11 is selected, the game might proceed as follows.
  • Is the number greater than 8? (Yes)
  • Is the number greater than 12? (No)
  • Is the number greater than 10? (Yes)
  • Is the number greater than 11? (No)
Therefore, the number must be 11. At each step, we choose a number right in the middle of the range of possible values for the number. For example, once we know the number is greater than 8, but less than or equal to 12, we know to choose a number in the middle of the range 12 (either 10 or 11 will do). At most \lceil\log_2 N\rceil questions are required to determine the number, since each question halves the search space. Note that one less question (iteration) is required than for the general algorithm, since the number is constrained to a particular range. Even if the number we're guessing can be arbitrarily large, in which case there's no upper bound N, we can still find the number in at most 2\lceil \log_2 k \rceil steps (where k is the (unknown) selected number) by first finding an upper bound by repeated doubling. For example, if the number were 11, we could use the following sequence of guesses to find it:
  • Is the number greater than 1? (Yes)
  • Is the number greater than 2? (Yes)
  • Is the number greater than 4? (Yes)
  • Is the number greater than 8? (Yes)
  • Is the number greater than 16? (No, N=16, proceed as above)
  • Is the number greater than 8? (Yes)
  • Is the number greater than 12? (No)
  • Is the number greater than 10? (Yes)
  • Is the number greater than 11? (No)
As one simple application, in revision control systems, it is possible to use a binary search to see in which revision a piece of content was added to a file. We simply do a binary search through the entire version history; if the content is not present in a particular version, it appeared later, while if it is present it appeared at that version or sooner. This is far quicker than checking every difference. However, most useful revision control systems provide some easier-to-use function for this purpose, such as CVS's annotate.

The algorithm

The most common application of binary search is to find a specific value in a sorted list. To cast this in the frame of the guessing game above, realize that we are now guessing the index, or numbered place, of the value in the list. The search begins by examining the value in the center of the list; because the values are sorted, it then knows whether the value occurs before or after the center value, and searches through the correct half in the same way. Here is simple pseudocode which determines the index of a given value in a sorted list a between indexes left and right:
  binarySearch(a, value, left, right)      if right < left          return not found      mid := floor((left+right)/2)      if amid = value          return mid      else if value < amid          binarySearch(a, value, left, mid-1)      else if value > amid          binarySearch(a, value, mid+1, right) 
Because the calls are tail-recursive, this can be rewritten as a loop so that it requires only constant space:
  binarySearch(a, value, left, right)      while left <= right          mid := floor((left+right)/2)          if amid = value              return mid          else if value < amid              right := mid-1          else if value > amid              left  := mid+1      return not found 
In both cases, the algorithm terminates because on each recursive call or iteration, the range of indexes right minus left always gets smaller, and so must eventually become negative. Binary search is a logarithmic algorithm and executes in O(log n) time. Specifically, 1 + \log_2N iterations are needed to return an answer. It is considerably faster than a linear search. It can be implemented using recursion or iteration, as shown above, although in many languages it is more elegantly expressed recursively.

Language support

Many standard libraries provide a way to do binary search. C provides bsearch in its standard library. C++'s STL provides algorithm functions lower_bound and upper_bound. Java offers a binarySearch() method for the class java.util.Arrays.

Example implementations

C

This is a simple implementation of binary search on an array of integers in C based on the above pseudocode. Because typically C compilers don't optimize tail recursion, an iterative version would be better, but this code is for illustration only.
   #include       int binarySearch(int* a, int value, int left, int right)   {       int mid;       if (right < left)           return -1; /* number not found */       mid = (left+right)/2;       if (amid == value)           return mid;       else if (value < amid)           return binarySearch(a, value, left, mid-1);       else           return binarySearch(a, value, mid+1, right);   }      int main(int argc, char* argv[])   {       int array[] = {1, 3, 7, 42, 85, 89, 90};       int array_len = 7;       printf("The index of number 7 is %d (indexing starts at 0)\n",              binarySearch(array, 7, 0, array_len-1));       return 0;   } 

Common Lisp

Below is an (almost) direct translation of the pseudocode above, with an example of usage designed to mimic the main function of the C example.
  (defun binary-search (a value left right)    (unless (< right left)      (let ((mid (truncate (+ left right) 2)))        (cond ((= value (elt a mid))               mid)              ((< value (elt a mid))               (binary-search a value left (- mid 1)))              ((> value (elt a mid))               (binary-search a value (1+ mid) right))))))     (let* ((array '(1 3 7 42 85 89 90))         (array-len (- (length array) 1)))    (format t "The index of number 7 is ~a (indexing starts at 0)~%"      (binary-search array 7 0 array-len))) 

Applications to complexity theory

Even if we don't know a fixed range the number k falls in, we can still determine its value by asking 2\lceil\log_2k\rceil simple yes/no questions of the form "Is k greater than x?" for some number x. As a simple consequence of this, if you can answer the question "Is this integer property k greater than a given value?" in some amount of time then you can find the value of that property in the same amount of time with an added factor of log k. This is called a reduction, and it is because of this kind of reduction that most complexity theorists concentrate on decision problems, algorithms that produce a simple yes/no answer. For example, suppose we could answer "Does this n x n matrix have determinant larger than k?" in O(n2) time. Then, by using binary search, we could find the (ceiling of the) determinant itself in O(n2log d) time, where d is the determinant; notice that d is not the size of the input, but the size of the output.

 

<< PreviousWord BrowserNext >>
bobby charlton
barry lyndon
labour party (uk)
cell (biology)
buffy the vampire slayer (movie)
barter
berthe morisot
brand
balfour declaration
barnard college
benedictine
beyazid i
beyazid ii
boxing
bollywood
bowls
barcelonnette
believers baptism
bah' faith
bubble sort
bavarii
burgundians
dots and boxes
big brother (1984)
bergen
bab
belle & sebastian
birth control
broadcast domain
big ben
beechcraft
battle of peleliu
battle of stalingrad
bodhidharma
biconditional introduction
biconditional elimination
base pair
baltimore ravens
british national party
batavii
baptism
bocce
beatmatching
baptism for the dead