Binary Search
Binary search is an efficient O(log(N))
algorithm for finding elements in a sorted array. It's important that the array is sorted. Binary Search doesn't work on unsorted arrays.
Auto Guess
We previously created a guessing game app that picked a random number and had you guess what it was until you got it correct.
Now we want to make the game guess the number automatically, in as few guesses as possible without teaching.
Binary Search finds items quickly by guessing an array index where an element might be, reading the value at that index, and basing it's next guess on what value it read. If the value at the index was less than the value it's searching for its next guess will be a higher index. It chooses a lower index if the value read was higher than what it is looking for.
Consider How You Use Phonebooks
Imagine flipping through a phone book to find someone's number. A linear O(N) algorithm would start at the beginning of the phone book and read every name on every page until it found the name you're looking for. This is terribly slow!
Instead of reading every single name it's much easier to read one random name and flip far forward or backward depending on how close that name is to the name you're looking for.
This only works because the phone book is sorted by names. Imagine trying to do a reverse look up on a mysterious phone number using a phone book. You'd have to start at the beginning and look at every single entry!
How Fast is Fast?
Imagine we had an array where every array access took 1 second. No matter what index we read it would take a full second for us to get the value. It would take us a minute to read every item in an item with only 60 items in it.
How long is a trillion seconds?
1,000 seconds is equal to almost 17 minutes.
It would take almost 12 days for a million seconds to elapse
It takes about 31.7 years for a billion seconds to go by.
A trillion seconds amounts to no less than 31,709.8 years.
It would take practically 31,709 years to search iteratively through an array with one trillion items.
With binary search it would take only 40 guesses to find the correct index. Binary Search reduced the runtime of searching for something in the trillion-length array from 31,709 years to only 40 seconds!
Binary Search is extremely fast.
Implement It
Your task is to implement this algorithm. Algorithms like these are language independent, meaning the language syntax may change but the logical flow is always the same. Binary Search is a recursive function and it runs until it finds the index of the value being searched for or until the portion of the array it is searching contains no elements.
Function takes four parameters: the array (
arr
), the search value (val
), the starting index (start
), and the ending index (end
).start
andend
are optional parameters (for the first call). Givestart
a default value of 0 and giveend
a default value ofnull
.Inside your function, you must detect if
end
isnull
. If it is, you need to then set it toarr.length - 1
so it holds the last index in the array.Find the index midway between
start
andend
. (Not important if it isn't exactly midway.)Compare the value at the
mid
index to the value (val
) being searched for.If it matches, return that index (
mid
).If the value at
mid
is greater thanval
then recurse on the left half of the array.Call
binarySearch
again with the samearr
and the sameval
but change thestart
andend
:For the left half, use the same index for
start
but usemid - 1
for theend
value.
If the value at
mid
is less thanval
then recurse on the right half of the array.Call
binarySearch
again with the samearr
andval
but changestart
andend
:For the right side, use
mid + 1
forstart
and use the existing index inend
.
If ever your
start
index is greater than yourend
index, you are immediately done. Return-1
to indicate that the value was not found in the array.
You may assume the given array is sorted. Your code must handle the case when the array is empty.
Thought Experiment
Binary Search is able to return useful information even if the element isn't even in the array.
What happens when an element isn't in a array?
Here's what happens when Binary Search runs:
It can actually return an index representing where an element should be. Instead of manually returning -1
we can almost return the index of our last guess. The index of our last guess represents where the element would be if it were in the array. Then, we could manually add the item at exactly the correct index and the array would remain sorted.
If we simply return the index of our last guess how would users of our algorithm tell the difference between when the number was found, and when we're trying to tell them the index of where it should go?
Instead of returning the index return the negative index! Now any positive number that comes back from the binary search represents that the element was found there. Any negative number that comes back from the array means that the element wasn't found, but we can do some math on the result and determine where it should be added.
Wait. What's negative zero? Still just zero.
There's one small problem. The zero-index of arrays complicates the idea that we can simply return the negative index of our last guess. If the algorithm returned zero it would be impossible to tell if it meant it found the element at zero, or if it means the element wasn't found and it should be added at element zero.
Instead of returning -guess
return -(guess - 1)
. This shifts zero indexes from zero to negative one. And now our algorithm truly fits these rules:
binarySearch(n) >= 0
is the index of the element in the arraybinarySearch(n) < 0
means the element wasn't found.
If binary search returns a negative number we can add 1 to it and negate it to determine where a non-found element should be inserted.
Last updated