二分查找是在有序列表中寻找目标值的一种快速方法。你先检查中间项,排除剩余值中的一半,然后重复这个过程。如果列表没有排序,这个逻辑就不成立。

对于升序列表,规则很简单:如果中间值小于目标值,就向右查找;如果中间值大于目标值,就向左查找。因为搜索范围会不断缩小到原来的一半左右,所以二分查找的时间复杂度是 O(logn)O(\log n)

二分查找如何在有序列表上工作

使用下面这个有序列表:

[3,7,12,18,24,31,39,45,52][3, 7, 12, 18, 24, 31, 39, 45, 52]

假设目标值是 3131

从整个范围开始。中间值是 2424。因为 31>2431 > 24,所以 2424 左边的所有元素都可以排除,搜索继续在

[31,39,45,52][31, 39, 45, 52]

现在中间值是 3939。因为 31<3931 < 39,所以 3939 右边的所有元素都可以排除,于是范围变成

[31][31]

现在中间值就是 3131,所以搜索停止。这里有用的想法不只是找到了目标值,而是只用了两次比较,候选范围就从 99 个值缩小到了 11 个。

为什么二分查找是 O(logn)O(\log n)

每次比较都会排除大约一半的剩余候选项。经过一步后,大约还剩 n/2n/2 个元素。经过两步后,大约还剩 n/4n/4 个元素。经过 kk 步后,剩余规模大约是

n2k\frac{n}{2^k}

当这个量大约变成 11 时,搜索就结束了,因此步数满足

2kn2^k \approx n

对两边取 log2\log_2,得到

klog2nk \approx \log_2 n

这就是为什么二分查找具有良好的扩展性。线性查找最多可能需要检查 nn 次,但二分查找只需要不断把范围减半所需的那些检查次数。

二分查找代码示例

下面是一个标准的 Python 迭代版本:

需要解题帮助?

上传你的问题,几秒钟内获得经过验证的分步解答。

打开 GPAI Solver →