📄 Need a professional CV? Try our Resume Builder! Get Started

Binary Search Algorithm Explained - Iterative & Recursive Methods in Python

Binary Search is an efficient algorithm for finding an item from a sorted list of elements. It repeatedly divides the search space in half. This explanation covers the iterative and recursive methods, edge cases, and performance considerations.

By using Binary Search, we achieve a time complexity of O(log n), which is much better than the O(n) time complexity of linear search.

Written by: Nerchuko

Sun Jan 5, 2025

Watch the Video Explanation

For a more detailed explanation of Binary Search, watch this video where I walk you through the concept and implementation in-depth:

Iterative vs Recursive Methods

Iterative Method

In the iterative approach, we use a loop to iteratively reduce the search space by adjusting the `low` and `high` pointers. This is memory efficient because no additional space is used for function calls.


def binary_search(arr, x):
    low = 0
    high = len(arr) - 1
    while low <= high:
        mid = (low + high) // 2
        if arr[mid] == x:
            return mid  # Target found
        elif arr[mid] > x:
            high = mid - 1  # Search in left half
        else:
            low = mid + 1  # Search in right half
    return -1  # Target not found
                        

Recursive Method

The recursive approach divides the search space into smaller subarrays through function calls. It offers a clean implementation but incurs additional space complexity due to recursive call stack.


def binary_search_recursive(arr, x, low, high):
    if low > high:
        return -1  # Base case: element not found
    mid = (low + high) // 2
    if arr[mid] == x:
        return mid  # Target found
    elif arr[mid] > x:
        return binary_search_recursive(arr, x, low, mid - 1)  # Search in left half
    else:
        return binary_search_recursive(arr, x, mid + 1, high)  # Search in right half
                        

Time and Space Complexity Analysis

Both iterative and recursive methods for Binary Search have the same time complexity of O(log n), but differ in space complexity:

Time Complexity:

  • Best Case: O(1) – The target is at the middle of the array.
  • Average Case: O(log n) – The search space is halved with each iteration or recursion.
  • Worst Case: O(log n) – The search space is halved at each step, with the target found at the last possible position.

Space Complexity:

  • Iterative Method: O(1) – Constant space, as it uses only a few variables for the search process.
  • Recursive Method: O(log n) – Additional space is used for the recursive call stack.

In most scenarios, the iterative method is preferred due to lower space complexity. However, the recursive approach can provide cleaner and more concise code.

Handling Edge Cases

Binary Search needs to handle edge cases efficiently to avoid errors. Below are a few edge cases you should be aware of:

1. Empty Array

If the array is empty, the search should return -1 immediately, as there are no elements to search.

2. Single Element Array

If the array has only one element, the target is either found or not. This case should return the correct index or -1.

3. Target at the Beginning or End

The target may be at the beginning (arr[0]) or the end (arr[len(arr)-1]) of the array. The algorithm must correctly identify and return the index in these cases.

4. Target Not in the Array

If the target is not present in the array, the algorithm should return -1 after exhausting the search space.

Output Example

For the array [3, 4, 5, 7, 8, 9, 10, 12, 15, 19, 20, 21, 22, 24, 25], when the target is 22, both methods (iterative and recursive) return the index 10.


arr = [3, 4, 5, 7, 8, 9, 10, 12, 15, 19, 20, 21, 22, 24, 25]
target = 22
print(binary_search(arr, target))  # Iterative Method Output: 10
print(binary_search_recursive(arr, target, 0, len(arr) - 1))  # Recursive Method Output: 10
                        

Binary Search: Finding 22 in Sorted Array

Middle Element
Target (22)
Eliminated Range

Initial Array

03
14
25
37
48
59
610
712mid
815
919
1020
1121
1222
1324
1425
Start: middle = 7, arr[7] = 12 < 22, so search right half

Step 1: Search Right Half

03
14
25
37
48
59
610
712
815
919
1020mid
1121
1222
1324
1425
Middle = 10, arr[10] = 20 < 22, so search right half again

Final Step: Found Target

03
14
25
37
48
59
610
712
815
919
1020
1121
1222found!
1324
1425
Target 22 found at index 12!

Algorithm Summary

  • Time Complexity: O(log n)
  • Space Complexity: O(1) iterative, O(log n) recursive
  • Requires sorted array
  • Divides search interval in half each step