Skip to content

二分查找

Binary search

在有序数组中反复排除一半候选区间的查找算法。

条目类型
算法

形式陈述

数组 A[0..n) 依某全序非降排列,目标为 x。二分查找维护候选区间 [,r),初始为 [0,n);每步取中点

m=+r2,

A[m]x 比较后弃掉不可能含目标的一半:A[m]<x 时令 m+1A[m]>x 时令 rm,相等则命中。其循环不变式为“若 x 在数组中,则它的某个位置落在 [,r) 内”;每步区间长度严格缩小且至少近似减半,故至多 log2n+1 次比较后终止。更一般的形式作用于单调谓词 P:{0,,n}{,}(自某处起由假翻真):不变式改为“ 之前全假、自 r 起全真”,算法返回第一个使 P 为真的下标;“求第一个不小于 x 的位置”即取 P(i)A[i]x 的特例。

直觉

排序把一次比较从“关于一个元素的信息”升级为“关于一整段的信息”:既然 A[m]<x,那么 A[0..m] 整段都小于 x,一次比较排除一半候选,这正是猜数游戏每问砍半的策略。信息论图像在单调谓词版本中最精确:每次询问 P(m) 只返回真或假一比特,而答案是 n+1 个可能分界位置之一,故最坏至少需要 log2(n+1) 次询问,二分达到同一数量级。精确查找时比较 A[m]x 有小于、等于、大于三种结果,不能逐字说成“一次比较只有一比特”;但受有序结构约束的比较决策树仍给出 Θ(logn) 的最坏界,二分同样在渐近意义下最优。真正的工程难点不在思想而在不变式纪律:区间开闭的语义、中点归入哪一半、每步是否严格缩小区间、重复元素时返回哪一个,都由所选不变式一锤定音,凭感觉增删 ±1 是错误的高发路径。定宽整数下 +r 还可能溢出,稳妥写法是 m=+(r)/2

二分查找半开区间收缩示意图
例子与边界

[1,3,3,7,9] 中查找 7=0,r=5m=2A[2]=3<7,故 =3m=4A[4]=9>7,故 r=4m=3A[3]=7 命中——三次比较,而逐项扫描最坏需五次。若改问“第一个不小于 3 的位置”,答案是下标 1;此时必须改用单调谓词版的不变式,“相等即停”的写法在重复键上返回的是不确定的某一个出现位置。

未排序的数组没有“排除一半”的依据:在 [2,9,4] 中查找 4,中点 A[1]=9>4 会把算法引向左半 [2],与真实位置失之交臂——排序假设一旦缺失,算法安静地给出错误答案而非报错。复杂度结论还依赖 O(1) 随机访问:链表上定位中点本身就要 O(n),二分不再有利。区间必须每步严格缩小:闭区间写法中若用 m=(+r)/2 搭配 m,则在 r=+1m=、区间原地不动,循环永不终止。

推论与应用

单调谓词形式把二分从查表扩展为“答案二分”:只要可行性关于参数单调(容量越大越可行之类),就能用对数次可行性判定逼出最优值,这是把判定器升级为优化器的通用手法。连续版本是实数区间上的对分法,依托介值定理逼近方程的根,每步精度翻倍。结构化版本是二叉搜索树,把中点比较固化为指针分叉以支持动态插删。而“每次比较至多一比特信息”的计数论证,同样是比较排序下界的核心。

本页的 O(logn) 是有序数组、常数时间随机访问和比较模型下的最坏查询界。前驱问题把“找最后一个不超过 x 的键”提升为可跨模型比较的接口,整数 Word-RAM 能利用键的 bit 结构突破普通比较树路线;分数级联在许多相关有序表之间复用一次定位,把重复二分的成本压到一次对数加线性表数。若数据主要驻留外存,缓存无关搜索树关注的是块传输而非比较次数。三者都从二分的分界思想出发,却改变了问题批次或机器模型。

参考资料
  • Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein, Introduction to Algorithms, 4th ed., MIT Press, 2022, §2.3 and exercises。
  • Donald E. Knuth, The Art of Computer Programming, Vol. 3: Sorting and Searching, 2nd ed., Addison-Wesley, 1998, §6.2.1。
关系图谱6 个相邻概念 · 2 类关系

拖动节点调整位置。

显示关系

显示:依赖

  1. 前置三跳
  2. 前置二跳
  3. 前置一跳
  4. 当前条目
  5. 后续一跳
  6. 后续二跳
  7. 后续三跳
文字版关系按与当前条目的最短距离分组
类型化关系

被这些条目使用