Home > Blockchain >  Infinite loop in binary search algorithm
Infinite loop in binary search algorithm

Time:11-27

I'm a newbie in algorithms. I have recently started studying binary search and tryed to implement it on my own. The task is simple: we have an array of integers a and an integer x. If a contains x the result should be its index, otherwise the function should return -1.

Here is the code I have written:

def binary_search(a, x):
    l = 0
    r = len(a)
    while r - l > 0:
        m = (l   r) // 2
        if a[m] < x:
            l = m
        else:
            r = m
    if a[l] == x:
        return l
    return -1

But this code stucks in infinite cycle on a = [1, 2] and x = 2. I suppose, that I have incorrect cycle condition (probably, should be r - l >= 0), but this solution does not help. Where am I wrong?

CodePudding user response:

Let me do some desk checking. I'll assume a = [1, 2] and we are searching for a 2

So we start with

l = 0
r = 2

Since r - l = 2 > 0, we enter the while-loop.

m = (l   r) / 2 = (0   2) / 2 = 1
a[m] = a[1] = 2 == x  (hence not less than x)
r = m = 1 (and l remains the same)

Now r - l = 1 - 0 = 1 > 0, so we continue

m = (l   r) / 2 = (0   1) / 2 = 0
a[m] = a[0] = 1 < x
l = m = 0 (and r remains the same)

After this iteration both r and l have the same value as before, which then produces an endless loop.

Ashok's answer is a great fix. But I think it'll be educational to do some desk checking on the fixed code and look what improves it.

Basically the problematic situation arises, when l 1 = r. Then m will always evaluate to l, a[l] < x and l is set to m again, which doesn't change the situation.

In a larger piece of code it'll make sense to make a table that contains a column for each variable to watch and a column to write down the code line that was evaluated. A column for remarks won't harm either.

CodePudding user response:

As Mani mentioned you are not considering when A[m]==x. Include that case (at that point you've found a so just return m), and once you have that case we can let l=m 1 when we are still below x. Like this:

def binary_search(a, x):
    l = 0
    r = len(a)
    while r - l > 0:
        m = (l   r) // 2
        if a[m] < x:
            l = m   1
        elif a[m]==x:
            return m
        else:
            r = m
    if l<len(a) and a[l] == x:
        return l
    return -1
  • Related