(d2)有序向量:二分查找
掌握三种区间写法的边界细节,看清折半背后的陷阱
按 空格/→ 演示下一步
全部页面点击任意一页,跳回舞台从这页播放
(d2)有序向量:二分查找
掌握三种区间写法的边界细节,看清折半背后的陷阱
概述
查英汉字典时,你不会从 a 一路翻到 z——而是直接翻到中间,按"偏前/偏后"判断,每次砍掉一半。这就是二分查找的核心思路。
每次猜中间数,按偏大/偏小砍掉一半,步数恰为 log₂n
接口
二分查找快得惊人——但前提是输入「对得上」、接口「讲得清」。这一页把接口摊开,看清它承诺什么、不承诺什么。
字典按字母排序=单调性;翻到中部=折半;查到词条即返回秩
语义
我们已经知道二分查找的接口形态,但它到底在'找'什么?返回位置又意味着什么?这一页把语义钉死——否则后续看代码会一直被细节困扰。
字典告诉你'应在第几页',即使未找到也给出插入位置
原理
前几页我们看了二分查找的「是什么」(概述)、「怎么用」(接口)、「返回什么」(语义)。这页钻进机制:凭什么它比顺序查找快这么多?核心只有四个字——折半淘汰。
不会从第一页翻到最后一页——先翻中间,根据字母序决定往前半还是后半,每次砍掉一半页码
实现
原理说每次砍一半范围。但落到代码上全是细节:循环用 lo<=hi 还是 lo<hi?中点怎么算不溢出?找不到返回什么?这页就拆这些坑。
两种都对,但混用就出错;选一个就一路用到底
实例
翻英语词典查 'binary'——你不会从 A 翻到 Z,而是直接翻到字典中段,看首字母落在哪个字母区间,再决定往前翻还是往后翻。这就是二分查找的典型场景。下面看几个具体例子。
每次看当前页首字母落到哪个字母段,再决定向前或向后翻——区间每步折半
查找长度
上一节我们用二分查找命中了目标。但每次成功需要比较几次?为什么有时快有时慢?这就要引入「查找长度」——度量查找效率的统一标尺。
每猜一次、对方答一次「大了/小了」就是一次比较;总共猜几次就是查找长度
本节要点
- ✓O(log n) 源于决策树高度,不是循环次数本身
- ✓lo/hi/mid 的分界语义即不变式,代码只是表达
- ✓n=0、1、2 的退化情形是验证正确性的试金石
- ✓失败查找总比成功多一层比较,体现在 ASL 公式上
课后思考
先自己想想,再看参考答案。三题分别对应核心、应用和迁移。
参考答案关键是顺序存储加有序性,可以 O(1) 随机访问下标。破坏场景:链表无法随机访问,频繁插入删除的动态场景也不再适用。
参考答案找到后不立即返回,继续向左二分直到左邻不等于目标或越界。经典做法是用 lower_bound 思路收缩右边界。
参考答案不能。链表访问中点需要 O(n) 遍历,整体退化为 O(n)。二分的高效建立在顺序存储的 O(1) 随机访问上。