EXPERIMENT 01 · BINARY SEARCH
二分查找(Binary Search)图解:窗口怎样缩小
同一组数字,两种更新规则。看一个窗口抵达答案,另一个停在原地。
0 起始下标
同步对照 / SAME INPUT, TWO RULES
FRAME 01 / 05A跳过 mid,继续缩小
lo = mid + 1 / hi = mid - 1
窄屏可左右滑动图示;下方数值显示完整区间
B留下 mid,窗口会停滞
lo = mid / hi = mid
窄屏可左右滑动图示;下方数值显示完整区间
第 1 步。正确轨道:a[3] = 7 < 13;下一步 lo = mid + 1 = 4。跳过已比较的 mid,窗口严格缩小。 错误轨道:a[3] = 7 < 13;下一步 lo = mid = 3。错误更新仍保留已比较的 mid。
TAKEAWAY
每一步,都要让问题变小。
保留 mid 并不一定每次都失败,但一旦新区间与旧区间相同,下一轮会重复同一次比较。本演示识别停滞后停止,不实际执行无限循环。
TRY TO EXPLAIN
[1, 3] 找 3,为什么 lo = mid 会卡住?
第一次 mid = 0,a[0] = 1。lo = mid 使窗口仍为 [0, 1];正确的 lo = mid + 1 将窗口变为 [1, 1],下一轮命中 3。
看完图,带走这些结论
二分查找在有序数组中比较中点,每轮排除不可能的一半。本页闭区间版本命中时返回一个匹配下标,否则返回 -1。
适用条件与边界
输入按非下降顺序排列,允许重复;数组可随机访问。重复目标只保证找到一个,不保证最左或最右。空数组直接返回 -1。图形输入限制为 1–8 个 ±999 整数,这不是算法本身的限制。
始终保持的规律
目标若存在,就仍在闭区间 [lo, hi] 中。正确更新为 lo = mid + 1 或 hi = mid - 1;lo > hi 时返回 -1。
逐步例子
- 在 [1, 3, 5, 7, 9] 中找 9:lo = 0,hi = 4,mid = 2,a[mid] = 5 < 9。
- 排除中点及左侧:lo = 3,hi = 4,mid = 3,a[mid] = 7 < 9。
- 再令 lo = 4,hi = 4,mid = 4,命中 9,返回下标 4。
复杂度
迭代查找最坏时间 O(log n),额外空间 O(1);空数组 O(1)。不包含预先排序的成本,也不包含页面为动画保存轨迹的开销。
常见误区
- 闭区间未命中后写 lo = mid 或 hi = mid,可能保留同一窗口而停滞。不要混用闭区间和半开区间模板。
- 未排序就二分,排除一半的依据不成立;排序还会改变原始下标。
- C++ 使用 lo + (hi - lo) / 2 时,仍须保证下标和差值可表示;有符号整数溢出是未定义行为,本页小整数不模拟它。
自测与答案
[1, 3] 查找 3,第一次 mid = 0。若写 lo = mid,下一轮窗口是什么?
仍是 [0, 1],中点也仍是 0。窗口没有缩小。改成 lo = mid + 1 后窗口变为 [1, 1],下一轮命中。