###Binary search - Applicable to sorted Iterables
Binary search exploits the relational difference between the elements and hence can be implemented upon almost any types of iterable, whether it be array, list, linked-list, etc stored it sorted order.
BINARY_SEARCH(ITERABLE L, start, final, element_to_search):
IF start <= final:
middle = FLOOR[(start + final) / 2]
IF element_to_search < L[middle]:
RETURN BINARY_SEARCH(L, start, mid - 1, element_to_search)
ELSE IF element_to_search > L[middle]:
RETURN BINARY_SEARCH(L, mid + 1, final, element_to_search)
ELSE
RETURN middle
END IF
END IF
RETURN FALSE
END BINARY_SEARCH
Initially invoke with start as 0
and final as n
where n is the last index of iterable.
It compares the element at the middle of concerned domain with the element_to_search
.
Since the elements are in sorted order, it adjusts the range - the domain to look for accordingly.
Some fundas -
- Suppose the iterable is sorted in increasing order and if the
element_to_search
is greater than the element atmiddle
index, then it is for sure that if it exists, it will exist after this element. - Therefore, our concerned domain (the range in which we will be searching for our element) has been reduced to
[middle + 1, final]
from[start, final]
, half to be more precise. - Similarly, if the
element_to_search
is lesser than the element atmiddle
, our reduced domain would have been[start, middle - 1]
After every step the domain is reduced to half of what it used to be. And theryby it would be taking a maximum of log n steps before it could conclude a result.
The best case would be when theelement_to_search
is present atFLOOR[L.length / 2]
. Hence it will be fetched in a single step i.e. O(1).
The average as well as the worst case will be taking up O(log n).
**Note: log base 2. Also assumed iterable was pre-sorted. If not, an additional complexity for sorting must be added alongwith.