Binary Search: Iterative vs Recursive
Table of Contents + โ
You already know binary search finds a number in a sorted list fast. But when you sit down to write it, you have a choice to make. Do you use a loop? Or do you make the function call itself? Both work. Both are correct. The thing is, they use a slightly different amount of memory. So letโs write both. Weโll run both. Then youโll see exactly when to pick one over the other.
๐ฏ The Problem Weโre Solving
Say you have a sorted array. You want to find where a number sits. Binary search keeps cutting the search range in half until it lands on the answer. That halving is the smart part.
But the โkeep cutting in halfโ idea can be coded in two shapes:
- One way uses a loop that updates two pointers again and again. We call this iterative. It means the code repeats the work using a loop.
- The other way makes the function call itself on the smaller half each time. We call this recursive. It means the function calls itself to solve a smaller piece of the same problem.
The pain point is simple. Beginners often learn only one shape. Then they freeze in an interview when asked for the other. So weโll learn both today. After this, youโll never freeze.
๐ง A Quick Real-World Picture
Think about looking for a name in a thick phone book. You open the middle. The name you want comes before that page. So you tear the book in half and keep only the left part. Then you open the middle of that part. You keep doing this.
- The iterative way is like keeping the same book in your hands. You just move your two thumbs closer each time.
- The recursive way is like handing the smaller half to a friend and saying โyou search this one.โ That friend hands an even smaller half to another friend. And so on.
Same idea. The recursive way just keeps passing the job along. Each friend remembers where they were. That โrememberingโ is what costs a little extra memory. Keep that in mind.
๐ How the Iterative Version Works
The iterative version keeps two markers. One marks the start of the range, called low. One marks the end of the range, called high. Then a loop runs while the range is still valid.
Here is what happens on each pass of the loop:
- Find the middle index with
mid = low + (high - low) / 2. We write it this way so the numbers donโt get too big and overflow. - If the value at
midis the target, we found it. Returnmid. - If the value at
midis less than the target, the answer must be on the right side. So movelowtomid + 1. - If the value at
midis greater than the target, the answer must be on the left side. So movehightomid - 1.
When low goes past high, the range is empty. The number is not there. So we return -1.
Tip
Why low + (high - low) / 2 and not (low + high) / 2? On very large arrays, low + high can grow bigger than the number type can hold. That bug is called overflow. The longer form avoids it and gives the same middle.
Steps to write iterative binary search:
- Set
low = 0andhigh = n - 1. - Loop while
low <= high. - Compute
mid = low + (high - low) / 2. - If
arr[mid] == target, returnmid. - If
arr[mid] < target, setlow = mid + 1. - Else set
high = mid - 1. - If the loop ends with no match, return
-1.
๐ How the Recursive Version Works
The recursive version does the same halving. But instead of a loop, it calls itself with a smaller range. We pass low and high into the function. Each call checks the middle. Then it calls itself again on either the left half or the right half.
Every recursive function needs a base case. That is the condition that stops the calls so they donโt go on forever. Here the base case is low > high. That means the range is empty. So we return -1.
Steps to write recursive binary search:
- The function takes
arr,low,high, andtarget. - Base case: if
low > high, return-1. - Compute
mid = low + (high - low) / 2. - If
arr[mid] == target, returnmid. - If
arr[mid] < target, call the function again withlow = mid + 1. - Else call the function again with
high = mid - 1.
The first call starts with low = 0 and high = n - 1. Just like before.
๐ป Both Versions in Code
Each tab below shows the iterative version first. Then it shows the recursive version. We search for the number 23 in a sorted array.
# Iterative: uses a loop and two markersdef search_iterative(arr, target): low, high = 0, len(arr) - 1 while low <= high: mid = low + (high - low) // 2 # middle, overflow-safe if arr[mid] == target: return mid # found it if arr[mid] < target: low = mid + 1 # go right else: high = mid - 1 # go left return -1 # not found
# Recursive: the function calls itself on the smaller halfdef search_recursive(arr, low, high, target): if low > high: # base case: empty range return -1 mid = low + (high - low) // 2 if arr[mid] == target: return mid if arr[mid] < target: return search_recursive(arr, mid + 1, high, target) # right half return search_recursive(arr, low, mid - 1, target) # left half
arr = [2, 5, 8, 12, 16, 23, 38, 56, 72, 91]
print("Iterative found 23 at index:", search_iterative(arr, 23))print("Recursive found 23 at index:", search_recursive(arr, 0, len(arr) - 1, 23))The output of the above code will be:
Iterative found 23 at index: 5Recursive found 23 at index: 5Note
Both versions find 23 at index 5. Same answer, same number of comparisons. The only difference is the shape of the code and the memory each one uses while running.
โ๏ธ The Real Trade-off: Memory
Here is the part most beginners miss. Both versions take O(log n) time. That is because both cut the range in half each step. Time is a tie. The difference is space.
Let me show you what happens to memory in each one:
- The iterative version uses the same two variables the whole time, just
lowandhigh. So its extra memory stays fixed no matter how big the array is. That is O(1) space. It means constant extra memory. - The recursive version makes a new function call for each halving step. Each call waits for the one inside it to finish. The computer stacks these waiting calls in memory. That stack of waiting calls is called the call stack. With about log n halvings, you get about log n calls waiting. That is O(log n) space.
So the picture is:
- Recursive reads cleaner. It matches the โdivide and conquerโ idea word for word.
- Iterative uses less memory. It never risks the call stack getting too deep.
Caution
On a normal sorted array, log n is small. So the recursive call stack is no problem at all. But the recursion idea matters a lot when you canโt easily write a loop, like searching a tree. For a plain array, many people pick iterative just to keep memory steady. Both are correct.
๐ Iterative vs Recursive at a Glance
Here is the side-by-side so you can see both at once.
| What we compare | Iterative | Recursive |
|---|---|---|
| Time complexity | O(log n) | O(log n) |
| Space complexity | O(1) constant | O(log n) call stack |
| How it repeats | A loop with low and high | The function calls itself |
| Readability | Clear, but more lines | Very clean, matches divide and conquer |
| Risk on huge input | None | Stack can get deep (rare for arrays) |
| Best for | Plain arrays, tight memory | Trees and divide-and-conquer code |
โ ๏ธ Common Mistakes to Avoid
A few slips trip up almost everyone the first time. Watch for these:
- Writing
(low + high) / 2instead oflow + (high - low) / 2. On big arrays the first one can overflow. Use the safe form. - Forgetting the base case in the recursive version. With no
low > highcheck, the function keeps calling itself and crashes. - Using
low < highinstead oflow <= highin the loop. With<you miss the case where the target sits at the last single spot. - Setting
low = midorhigh = midinstead ofmid + 1andmid - 1. That leavesmidin the range again and the loop runs forever. - Running binary search on an array that is not sorted. Binary search only works on sorted data, so sort it first.
๐งฉ What Youโve Learned
โ Binary search can be written two ways: iterative with a loop, or recursive where the function calls itself.
โ Both take O(log n) time because both cut the search range in half each step.
โ
The iterative version uses O(1) extra space, just low and high.
โ The recursive version uses O(log n) space because each call waits on the call stack.
โ
Always use the overflow-safe middle low + (high - low) / 2, keep a base case in recursion, and only search sorted data.
Check Your Knowledge
Test what you learned. Pick an answer for each question, then click Check.
- 1
Why do iterative and recursive binary search have the same time complexity?
Why: Each step halves the range, so both need about log n steps to reach the answer.
- 2
What extra memory does the recursive version use compared to the iterative one?
Why: Each recursive call waits on the call stack, and there are about log n of them.
- 3
Why do we compute the middle as low + (high - low) / 2?
Why: Adding low and high directly can overflow on large arrays, while this form stays safe.
- 4
What is the base case in the recursive binary search?
Why: If low passes high, the range is empty and the function returns -1 to stop the calls.