Skip to content

Recursive Binary Search

Binary search implemented using recursion over a shrinking interval.

Recursive binary search expresses the same divide and conquer strategy as binary search, but uses function calls instead of a loop. Each call reduces the search interval by half.

This form is closer to the mathematical definition of the algorithm, though it introduces call stack overhead.

Problem

Given a sorted array AA of length nn and a value xx, find an index ii such that

A[i]=x A[i] = x

If no such index exists, return 1-1.

Algorithm

Define a recursive function over a subarray [l,r][l, r].

recursive_binary_search(A, x, l, r):
    if l > r:
        return -1

    m = l + (r - l) // 2

    if A[m] == x:
        return m
    else if A[m] < x:
        return recursive_binary_search(A, x, m + 1, r)
    else:
        return recursive_binary_search(A, x, l, m - 1)

Wrapper:

search(A, x):
    return recursive_binary_search(A, x, 0, length(A) - 1)

Example

Let

A=[1,4,6,8,11,15] A = [1, 4, 6, 8, 11, 15]

and

x=8 x = 8

Call sequence:

calllrmA[m]result
10526recurse right
235411recurse left
33338found

Return index 33.

Correctness

The recursion maintains the invariant:

  • If xx exists in AA, then it lies within the current interval [l,r][l, r]

Each recursive call reduces the interval size while preserving this invariant. When l>rl > r, the interval is empty, so no valid index exists.

Complexity

casetime
bestO(1)O(1)
worstO(logn)O(\log n)
averageO(logn)O(\log n)

Space complexity:

typespace
recursion stackO(logn)O(\log n)

Each recursive call adds one frame to the call stack.

Notes

  • This version matches the divide and conquer structure directly.
  • It is easier to reason about formally but less efficient in low level environments due to function call overhead.
  • Tail recursion elimination may convert this to an iterative form in some compilers, but this is not guaranteed.

Implementation

def recursive_binary_search(a, x, l, r):
    if l > r:
        return -1
    m = l + (r - l) // 2
    if a[m] == x:
        return m
    elif a[m] < x:
        return recursive_binary_search(a, x, m + 1, r)
    else:
        return recursive_binary_search(a, x, l, m - 1)
func RecursiveBinarySearch(a []int, x int, l, r int) int {
    if l > r {
        return -1
    }
    m := l + (r-l)/2
    if a[m] == x {
        return m
    } else if a[m] < x {
        return RecursiveBinarySearch(a, x, m+1, r)
    } else {
        return RecursiveBinarySearch(a, x, l, m-1)
    }
}