Demystify binary search! Unlock the secrets of Binary Search Algorithm with clear explanations and practical examples. Master this powerful search technique for efficient problem-solving.
Binary Search is a searching algorithm for finding an element's position in a sorted array.
In this approach, the element is always searched in the middle of a portion of an array.
Binary search can be implemented only on a sorted list of items. If the elements are not sorted already, we need to sort them first.
Binary Search Algorithm can be implemented in two ways which are discussed below.
The recursive method follows the divide and conquer approach.
The general steps for both methods are discussed below.
Initial array
Let x = 4
be the element to be searched.
Setting pointers
arr[(low + high)/2] = 6
.Mid element
x > mid
, compare x with the middle element of the elements on the right side of mid. This is done by setting low to low = mid + 1
.high = mid - 1
.Finding mid element
Mid element
x = 4
is found.Found
do until the pointers low and high meet each other.
mid = (low + high)/2
if (x == arr[mid])
return mid
else if (x > arr[mid]) // x is on the right side
low = mid + 1
else // x is on the left side
high = mid - 1
binarySearch(arr, x, low, high)
if low > high
return False
else
mid = (low + high) / 2
if x == arr[mid]
return mid
else if x > arr[mid] // x is on the right side
return binarySearch(arr, x, mid + 1, high)
else // x is on the left side
return binarySearch(arr, x, low, mid - 1)
Python
# Binary Search in python
def binarySearch(array, x, low, high):
# Repeat until the pointers low and high meet each other
while low <= high:
mid = low + (high - low)//2
if array[mid] == x:
return mid
elif array[mid] < x:
low = mid + 1
else:
high = mid - 1
return -1
array = [3, 4, 5, 6, 7, 8, 9]
x = 4
result = binarySearch(array, x, 0, len(array)-1)
if result != -1:
print("Element is present at index " + str(result))
else:
print("Not found")
Java
// Binary Search in Java
class BinarySearch {
int binarySearch(int array[], int x, int low, int high) {
// Repeat until the pointers low and high meet each other
while (low <= high) {
int mid = low + (high - low) / 2;
if (array[mid] == x)
return mid;
if (array[mid] < x)
low = mid + 1;
else
high = mid - 1;
}
return -1;
}
public static void main(String args[]) {
BinarySearch ob = new BinarySearch();
int array[] = { 3, 4, 5, 6, 7, 8, 9 };
int n = array.length;
int x = 4;
int result = ob.binarySearch(array, x, 0, n - 1);
if (result == -1)
System.out.println("Not found");
else
System.out.println("Element found at index " + result);
}
}
C programming
// Binary Search in C
#include <stdio.h>
int binarySearch(int array[], int x, int low, int high) {
// Repeat until the pointers low and high meet each other
while (low <= high) {
int mid = low + (high - low) / 2;
if (array[mid] == x)
return mid;
if (array[mid] < x)
low = mid + 1;
else
high = mid - 1;
}
return -1;
}
int main(void) {
int array[] = {3, 4, 5, 6, 7, 8, 9};
int n = sizeof(array) / sizeof(array[0]);
int x = 4;
int result = binarySearch(array, x, 0, n - 1);
if (result == -1)
printf("Not found");
else
printf("Element is found at index %d", result);
return 0;
}
C++
// Binary Search in C++
#include <iostream>
using namespace std;
int binarySearch(int array[], int x, int low, int high) {
// Repeat until the pointers low and high meet each other
while (low <= high) {
int mid = low + (high - low) / 2;
if (array[mid] == x)
return mid;
if (array[mid] < x)
low = mid + 1;
else
high = mid - 1;
}
return -1;
}
int main(void) {
int array[] = {3, 4, 5, 6, 7, 8, 9};
int x = 4;
int n = sizeof(array) / sizeof(array[0]);
int result = binarySearch(array, x, 0, n - 1);
if (result == -1)
printf("Not found");
else
printf("Element is found at index %d", result);
}
Python
# Binary Search in python
def binarySearch(array, x, low, high):
if high >= low:
mid = low + (high - low)//2
# If found at mid, then return it
if array[mid] == x:
return mid
# Search the left half
elif array[mid] > x:
return binarySearch(array, x, low, mid-1)
# Search the right half
else:
return binarySearch(array, x, mid + 1, high)
else:
return -1
array = [3, 4, 5, 6, 7, 8, 9]
x = 4
result = binarySearch(array, x, 0, len(array)-1)
if result != -1:
print("Element is present at index " + str(result))
else:
print("Not found")
Java
// Binary Search in Java
class BinarySearch {
int binarySearch(int array[], int x, int low, int high) {
if (high >= low) {
int mid = low + (high - low) / 2;
// If found at mid, then return it
if (array[mid] == x)
return mid;
// Search the left half
if (array[mid] > x)
return binarySearch(array, x, low, mid - 1);
// Search the right half
return binarySearch(array, x, mid + 1, high);
}
return -1;
}
public static void main(String args[]) {
BinarySearch ob = new BinarySearch();
int array[] = { 3, 4, 5, 6, 7, 8, 9 };
int n = array.length;
int x = 4;
int result = ob.binarySearch(array, x, 0, n - 1);
if (result == -1)
System.out.println("Not found");
else
System.out.println("Element found at index " + result);
}
}
C Programming
// Binary Search in C
#include <stdio.h>
int binarySearch(int array[], int x, int low, int high) {
if (high >= low) {
int mid = low + (high - low) / 2;
// If found at mid, then return it
if (array[mid] == x)
return mid;
// Search the left half
if (array[mid] > x)
return binarySearch(array, x, low, mid - 1);
// Search the right half
return binarySearch(array, x, mid + 1, high);
}
return -1;
}
int main(void) {
int array[] = {3, 4, 5, 6, 7, 8, 9};
int n = sizeof(array) / sizeof(array[0]);
int x = 4;
int result = binarySearch(array, x, 0, n - 1);
if (result == -1)
printf("Not found");
else
printf("Element is found at index %d", result);
}
C++
// Binary Search in C++
#include <iostream>
using namespace std;
int binarySearch(int array[], int x, int low, int high) {
if (high >= low) {
int mid = low + (high - low) / 2;
// If found at mid, then return it
if (array[mid] == x)
return mid;
// Search the left half
if (array[mid] > x)
return binarySearch(array, x, low, mid - 1);
// Search the right half
return binarySearch(array, x, mid + 1, high);
}
return -1;
}
int main(void) {
int array[] = {3, 4, 5, 6, 7, 8, 9};
int x = 4;
int n = sizeof(array) / sizeof(array[0]);
int result = binarySearch(array, x, 0, n - 1);
if (result == -1)
printf("Not found");
else
printf("Element is found at index %d", result);
}
Time Complexities
O(1)
O(log n)
O(log n)
Space Complexity
The space complexity of the binary search is O(1)
.
When working with arrays, you’ll often have to search through them to check if they contain a target element.
You can always run a sequential search—scanning the array from the beginning to the end—on the array. But if the array is sorted, running the binary search algorithm is much more efficient.
Let's learn how binary search works, its time complexity, and code a simple implementation in Python.
We'll start our discussion with linear or sequential search.
Suppose we have an unsorted sequence of numbers nums
. Given this nums array, you should check if the target
is present in nums
. You don’t have information about whether nums
is sorted.
So the only way you can do this is to scan the array in a linear fashion, starting at the first element—until you find a match.
You can loop through the entire array to check if the element at index i
matches the target
. Once you find a match, you can break out of the loop.
Notice that in the worst case, you’ll have to scan the entire array and be lucky enough to find a match at the last index. Or you’ll have exhausted the array—without finding a match—indicating that the element is not present in the array.
Suppose the array has n
elements. Because you have to scan the entire array—in the worst case—the linear search algorithm has a time complexity of O(n).
Here's an example:
Linear Search Example | Image by the author
But when you do not know anything about the sequence, this is the best you can do. So linear or sequential search is the best you can do when searching through unsorted sequences.
The function linear_search
takes in an array nums
and a target
to search for. It then loops through the array sequentially to check if target
is present in nums
:
def linear_search(nums,target):
for num in nums:
if num == target:
return True
return False
Here are a couple of sample outputs:
nums = [14,21,27,30,36,2,5,7,11]
target = 27
print(linear_search(nums,target))
# Output: True
target = 100
print(linear_search(nums,target))
# Output: False
Now consider the nums
sequence with n
elements sorted in ascending order. For any valid index k
, the following holds True
for the element a_k
at index k
:
The elements at indices 0, 1, 2, …, (k-1) are all less than or equal to
a_k
. And all elements at indices (k+1) to (n-1) are greater than or equal toa_k
.
With this information, you no longer need to run a linear scan. You can do it much faster with binary search.
We’re given a sorted array nums
and a target
. Let mid denote the middle-most index of the array and nums[mid]
denote the element at the middle index. Here’s how the binary search algorithm works:
nums[mid]
is equal to the target
. If so, we’ve already found a match—in the very first step—and the search terminates.nums[mid]
> target
, you only need to search the left half of the array. Even when you search through the left subarray you can use the same binary search algorithm.nums[mid]
< target
, you can ignore all the elements up to the middle element and only consider the right half of the array.Notice that we have a recurrence relation here. First, we start by running the binary search algorithm on the array with n elements. If we don't find the target in the very first step, we run binary search on the subarray of size at most n/2 elements.
If we end up with an empty array or an array with one element that is not the target
, we conclude that the target does not exist in the nums
array.
Binary Search Example | Image by the author
Here's a recursive implementation of binary search in Python:
def binary_search(nums,target,low,high):
if low > high:
return False
else:
mid = (low + high)//2
if nums[mid] == target:
return True
elif nums[mid] < target:
return binary_search(nums,target,mid+1,high)
else:
return binary_search(nums,target,low,mid-1)
With a few sample runs of the binary_search
function:
nums = [2,5,7,11,14,21,27,30,36]
target = 27
print(binary_search(nums,target,0,len(nums)-1))
# Output: True
target = 38
print(binary_search(nums,target,0,len(nums)-1))
# Output: False
In binary search, we know that the search space is reduced by half at each step and this guides us in computing the time complexity.
For an array with n
elements, we check if the middle-most element matches the target
. If so, we return True
and terminate the search.
But if the middle element does not match the target
, we perform binary search on a subarray of size at most n/2
. In the next step, we have to search through an array of size at most n/4
. And we continue this recursively until we can make a decision in a constant time (when the subarray is empty).
At step k
, we need to search through an array of size at most n/(2^k)
. And we need to find the smallest such k
for which we have no subarray to search through.
Mathematically:
The time complexity of binary search is, therefore, O(logn). This is much more efficient than the linear time O(n), especially for large values of n.
For example, if the array has 1000 elements. 2^(10) = 1024. While the binary search algorithm will terminate in around 10 steps, linear search will take a thousand steps in the worst case.
And that's a wrap. I hope you found this introduction to binary search helpful! You’ll often run into questions involving binary search in coding interviews.
#algorithms #binarysearch #datastructures