Python下面的二进制搜索代码有什么问题

时间:2015-09-30 01:55:07

标签: python sorting

让我们从功能角度说。感谢。

def binarySearch(array, beginIndex, endIndex, value):
    while (beginIndex < endIndex):
        mid = (beginIndex + endIndex) // 2
        if array[mid] < value:
            beginIndex = mid + 1
        elif array[mid] > value:
            endIndex = mid - 1
        else: #equal
            return mid

    if array[beginIndex] == value:
        return beginIndex
    else:
        return -1

以下是我测试的情况,

print binarySearch([2,3], 0, 1, 2)
print binarySearch([2,3], 0, 1, 3)
print binarySearch([2,3], 0, 1, -1)
print binarySearch([2,3,3,3,4,5], 0, 5, 3)
提前谢谢, 林

1 个答案:

答案 0 :(得分:-1)

嗯,第一件事“错误”(如果这是生产代码而不是课堂作业或个人练习)是你重新发明轮子。 Python已经通过bisect module提供二进制搜索作为所包含电池的一部分(是的,它也在Python 2上)。

除此之外,它绝对不适用于所有情况。例如,我刚试过:

binarySearch(list(range(1000)), 0, 1000, 6) # And again with 999 in case end index was inclusive

并没有受到重创。这是因为你的循环从未实际循环;大概你需要对最后的if/else表示不满,所以它不是while循环的一部分,因为你不会使它多于一个(半个,计算if/else)集合在成功或放弃之前进行的测试。

修复缩进问题(如果您使用的是Python 3或在Python 2上使用__future__ division导入,将/ 2更改为// 2)可以使其正常工作,它似乎是算法的一个相当标准的实现。

一些建议:

  1. Python倾向于使用半开范围;您接受beginIndexendIndex作为包含值,其中Python函数通常接受startend,其中start包含在内,end为独家(range表现的方式)。
  2. beginIndex/ endIndex`参数移动到配置文件的末尾将允许您为它们提供有用的默认值,因此在常见情况下(搜索整个序列),用户不必手动指定边界。例如:

    def binarySearch(array,value,beginIndex = 0,endIndex = None):     如果endIndex为None:         endIndex = len(array) - 1#或者只是len(数组),如果你重写为半开     ...

  3. 会使标准案例中的调用变得更加简单(并非巧合,这是bisect.bisect使用的配置文件)。

    在修复缩进问题时(根据评论中的请求),我说以下四行(当前缩进到while循环体的级别)应该缩小一个级别,所以它们只在while循环退出而没有return时运行,而不是每次执行while循环(因为在任一路径上有返回,意味着while循环永远不会实际循环):

    if array[beginIndex] == value:
        return beginIndex
    else:
        return -1