Consider the following problem:
L is a sorted list containing
n signed integers (
n being big enough), for example
[-5, -2, -1, 0, 1, 2, 4] (here,
n has a value of 7). If
L is known to contain the integer 0, how can you find the index of 0 ?
The first thing that comes to mind is to just read every index until 0 is found. In the worst case, the number of operations is
n, so the complexity is O(n).
This works fine for small values of
n, but is there a more efficient way ?
Consider the following algorithm (Python3):
a = 0 b = n-1 while True: h = (a+b)//2 ## // is the integer division, so h is an integer if L[h] == 0: return h elif L[h] > 0: b = h elif L[h] < 0: a = h
b are the indexes between which 0 is to be found. Each time we enter the loop, we use an index between
b and use it to narrow the area to be searched.
In the worst case, we have to wait until
b are equal. But how many operations does that take? Not n, because each time we enter the loop, we divide the distance between
b by about two. Rather, the complexity is O(log n).
Note: When we write "log", we mean the binary logarithm, or log base 2 (which we will write "log_2"). As O(log_2 n) = O(log n) (you can do the math) we will use "log" instead of "log_2".
Let's call x the number of operations: we know that 1 = n / (2^x).
So 2^x = n, then x = log n
When faced with successive divisions (be it by two or by any number), remember that the complexity is logarithmic.