###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_searchis greater than the element atmiddleindex, 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_searchis 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_searchis 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.