Suppose we have an array of integers, previously sorted in increasing numerical order. We want to know if some given integer is present in the array. The method shown in Figure 7.1
public static boolean contains(int item, int[] array) {
int low = 0;
int high = array.length - 1;
while (low <= high) {
int mid = (low + high) / 2;
if (item < array[mid]) {
high = mid - 1;
} else if (item > array[mid]) {
low = mid + 1;
} else {
return true;
}
}
return false;
}
|
In practice you are more likely to begin by looking at a word
somewhere near the middle. If that is your word, you are done.
Otherwise, if your word is earlier than that word, you can discard the
second half of the dictionary. If it is later, you can discard the
first half. Either way, you now have to search a dictionary only half
the previous size, and you have managed that with just one comparison!
Putting it the other way round, if you doubled the size of the
dictionary you would only have to make one extra comparison. Doing it
by sequential search, you would have to double the number of
comparisons. Doing it by binary search, you just add one. This is
the difference between
and
complexity. Notice that this improvement was only possible because
the words were assumed to be in their correct alphabetical order in
the dictionary.
Concerning the actual code, you should satisfy yourself that it really does terminate correctly. The tricky parts are the condition
low <= highand the assignment
mid = (low + high) / 2.It won't work if you use
< rather than
<= and you should worry about the value of mid in the cases where
low + high is odd or even. The method will return from within the while
loop if the item is present; otherwise it will exit the while
loop with
low > high and return false.