二进制搜索丢失的元素是否总是 return 元素就在它本来存在的位置之前?

Does the binary search for a missing element always return the element just before the place it would have been if it were present?

这类似于C++中的lower_bound,二进制搜索的Javadoc也提到了这一点:"index of the search key, if it is contained in the array; otherwise, (-(insertion point) - 1)."

我已经能够通过几个例子验证它是真的,而且我很确定它是真的。但是,我无法证明这一点,所以我不确定。

我试过用反证法来证明。它沿着这条线运行:如果该元素在那里,那么我们一定是通过消除包含该元素的范围而错过了它。潜在位置和它应该是的位置之间的差距必须是最小的。最后如果有两个元素,你检查第一个元素,要么是元素,要么是元素可能所在位置后面的元素。

我也曾尝试考虑将存在元素的情况减少到没有元素的情况,但这种方法无济于事。我觉得我在挥舞着证明并抓住了救命稻草。

问题中的陈述是否正确?如果是,你能证明吗?

这取决于您如何实现二分查找。

例如,按照您描述的方式实现它的一种方法是让它搜索大于或等于您的元素的第一个元素。然后,当二分搜索停止时,它停止的位置就是答案(实际元素或应插入的位置)。

示例代码:

binary_search(v: value to search, a: list to search in, n: list size):
    left = 0, right = n

    while left < right:
        m = (left + right) / 2
        if a[m] >= v: // this is the important part:
                      // even if we find it, we continue,
                      // so we find the first such value.
            right = m
        else:
            left = m + 1

    return left

示例输出:

binary_search(3, {1, 2, 4}, 3) = 2
binary_search(0, {1, 2, 3}, 3) = 0
binary_search(2, {1, 2, 3}, 3) = 1

这应该很容易适应您提到的格式的 return 值。

对于实现here,我们可以这样证明:如果元素找到了,那么它的位置显然是returned,所以我们重点关注没有找到的情况。最终,二分搜索循环将退出,因为 low == high + 1

让我们看看如果在退出之前找到该元素会发生什么,例如考虑 low = high = K。那么该元素将在位置 K 处找到。既然不是,我们将设置 low = K + 1high = K - 1.

由于未找到该元素,returning low 将 return 您感兴趣的内容。