正确的二进制搜索算法

Correct binary-search algorithm

下面这样写一个二分查找的实现可以吗?

    def binarySearching(sortedArr,v):
    if len(sortedArr)>=1:
        mid = len(sortedArr)//2
        if v<sortedArr[mid]:
            return binarySearching(sortedArr[:mid],v)
        elif v>sortedArr[mid]:
            return binarySearching(sortedArr[mid+1:],v)
        else:
            return mid
        return None

不明白为什么要指定lowhigh 为算法。

编辑:感谢@Stef,此实现不正确,因为 mid 不是原始数组,而是子数组

当您使用唯一的 array/list 时,您必须指定 low and high 。在每次迭代中,您都会处理 low..high 范围内的列表的一部分。

您的实现生成了子列表,因此不需要明确的范围定义(但是这个子列表的形成是免费的吗?)

使用二进制搜索算法时,每一步都会将搜索范围缩小一半。

您指定 lowhigh,因为您传递相同的数组进行搜索并仅更改搜索区域。

传递 lowhigh 的替代方法是传递数组的一部分,但在 python 中,这意味着每次切片数组(列表)时都会创建另一个对象(这是切片列表)-内存效率低下。

比较binarySearch的这两个实现。第一个是你的,第二个是我的

在您的版本中,您正在将“切片”(即子数组的完整副本)传递给递归调用。在我的版本中,所有递归调用都访问同一个数组而不复制它,而是仅将 lowhigh 作为参数传递。

# using slices, ie, copies of subarrays
def binarySearching(sortedArr,v):
    # print(sortedArr)
    if len(sortedArr)>=1:
        mid = len(sortedArr)//2
        if v<sortedArr[mid]:
            return binarySearching(sortedArr[:mid],v)
        elif v>sortedArr[mid]:
            return binarySearching(sortedArr[mid+1:],v)
        else:
            return mid
    else:
        return None

# using low and high indices
def otherBinarySearching(sortedArr, v):
    def auxiliary(low, high, v):
        #print(low, high, sortedArr[low:high])
        if high > low:
            mid = (high + low) // 2
            if v < sortedArr[mid]:
                return auxiliary(low, mid, v)
            elif v > sortedArr[mid]:
                return auxiliary(mid+1, high, v)
            else:
                return mid
        elif high == low:
            return (low if v == sortedArr[low] else None)
    return auxiliary(0, len(sortedArr), v)

# add some tests to make sure implementations are correct
if __name__=='__main__':
    a = [x for x in range(0, 101, 2)]
    b = [x for x in range(1, 100, 2)]
    print('a: ', a)
    print('b: ', b)
    print('binarySearching:      ', all(isinstance(binarySearching(a, x), int) for x in a) and all(binarySearching(a, x) is None for x in b))
    print('otherBinarySearching: ', all(otherBinarySearching(a, x) == x / 2 for x in a) and all(otherBinarySearching(a, x) is None for x in b))

此外,您的版本 returns 索引错误:行 [​​=14=] returns 子数组 binarySearching 当前正在查看的 v 的索引,而不是原始数组中的索引。