Implementing Binary Search
To implement binary search, we will start with a function
“binary_search”:
int binary_search(int a[], int n, int needle)
{
// ...
}
It takes as input:
- a – an array containing the haystack (sorted in increasing order of values);
- n – the size of the haystack;
- needle – the element we are looking for
and it outputs:
- -1 – if the needle is not in the haystack, or
- i – a position between 0 (inclusively) and n (exclusively) in the
haystack at which the needle occurs.
We start by initializing the two indices l and r as discussed above,
by the first and the last element in the array:
int binary_search(int a[], int n, int needle)
{
int l = 0;
int r = n - 1;
// ...
}
Recall that the property that the segment [l, r] fulfils is that the
needle is definitely between l and r, if it occurs at all in the
haystack.
We now loop for as long as the segment of interest contains at least
an element and therefore there is a chance of finding the needle:
int binary_search(int a[], int n, int needle)
{
int l = 0;
int r = n - 1;
while (l <= r) {
// ...
}
// ...
}
We now have to compute the middle of the segment [l, r] (rounded down to the nearest integer):
int binary_search(int a[], int n, int needle)
{
int l = 0;
int r = n - 1;
while (l <= r) {
int m = l + (r - l) / 2;
// ...
}
// ...
}
We now check if the needle is exactly at position m:
int binary_search(int a[], int n, int needle)
{
int l = 0;
int r = n - 1;
while (l <= r) {
int m = l + (r - l) / 2;
if (a[m] == needle) {
return m;
}
// ...
}
// ...
}
If not, then a[m] must be either strictly smaller or strictly larger
than the needle, in which cases we shorten the segment of interest accordingly:
int binary_search(int a[], int n, int needle)
{
int l = 0;
int r = n - 1;
while (l <= r) {
int m = l + (r - l) / 2;
if (a[m] == needle) {
return m;
} else if (a[m] < needle) {
l = m + 1;
} else { // a[m] > needle for sure
r = m - 1;
}
}
// ...
}
In the case where a[m] < needle, there is no chance to find
the needle to the left of m, as the elements to the left of m are even
smaller, and therefore we update l to m + 1.
In the last case, where a[m] > needle, there is no chance to find the
needle to the right of m, as the elements to the right of m are even
larger, and therefore we update r to m – 1.
Finally, if the segment of interest becomes empty without us having
found the needle, then surely the needle does not occur in the
haystack and therefore we return “-1”.
int binary_search(int a[], int n, int needle)
{
int l = 0;
int r = n - 1;
while (l <= r) {
int m = l + (r - l) / 2;
if (a[m] == needle) {
return m;
} else if (a[m] < needle) {
l = m + 1;
} else { // a[m] > needle for sure
r = m - 1;
}
}
return -1;
}
Check out the next page for caveats and possible variations of our implementation.
- Page 1 – Introduction
- Page 2 – How It Works – Overview
- Page 3 – Example 1
- Page 4 – Example 2
- Page 5 – Why Binary Search is so Fast
- Page 6 – Implementation
- Page 7 – Conclusion