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 of length and a value , find an index such that
If no such index exists, return .
Algorithm
Define a recursive function over a subarray .
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
and
Call sequence:
| call | l | r | m | A[m] | result |
|---|---|---|---|---|---|
| 1 | 0 | 5 | 2 | 6 | recurse right |
| 2 | 3 | 5 | 4 | 11 | recurse left |
| 3 | 3 | 3 | 3 | 8 | found |
Return index .
Correctness
The recursion maintains the invariant:
- If exists in , then it lies within the current interval
Each recursive call reduces the interval size while preserving this invariant. When , the interval is empty, so no valid index exists.
Complexity
| case | time |
|---|---|
| best | |
| worst | |
| average |
Space complexity:
| type | space |
|---|---|
| recursion stack |
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)
}
}