Binary Search: Iterative vs Recursive

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 mid is the target, we found it. Return mid.
  • If the value at mid is less than the target, the answer must be on the right side. So move low to mid + 1.
  • If the value at mid is greater than the target, the answer must be on the left side. So move high to mid - 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:

  1. Set low = 0 and high = n - 1.
  2. Loop while low <= high.
  3. Compute mid = low + (high - low) / 2.
  4. If arr[mid] == target, return mid.
  5. If arr[mid] < target, set low = mid + 1.
  6. Else set high = mid - 1.
  7. 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:

  1. The function takes arr, low, high, and target.
  2. Base case: if low > high, return -1.
  3. Compute mid = low + (high - low) / 2.
  4. If arr[mid] == target, return mid.
  5. If arr[mid] < target, call the function again with low = mid + 1.
  6. 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.

binary_search.py
# Iterative: uses a loop and two markers
def 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 half
def 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:

Output
Iterative found 23 at index: 5
Recursive found 23 at index: 5

Note

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 low and high. 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) / 2 instead of low + (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 > high check, the function keeps calling itself and crashes.
  • Using low < high instead of low <= high in the loop. With < you miss the case where the target sits at the last single spot.
  • Setting low = mid or high = mid instead of mid + 1 and mid - 1. That leaves mid in 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. 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. 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. 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. 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.

๐Ÿš€ Whatโ€™s Next?

Share & Connect