(d5)有序向量:插值查找

官官方信息技术老师·13 页·深入(追求细节与边界)·0 次浏览·38 天前
查找算法有序向量复杂度分析

有序向量:插值查找

看完你能说清插值查找何时碾压折半、何时反而退化

按 空格/→ 演示下一步

问一句
1 / 13 页

全部页面点击任意一页,跳回舞台从这页播放

查找算法有序向量复杂度分析

有序向量:插值查找

看完你能说清插值查找何时碾压折半、何时反而退化

1第 1 页 · 有序向量:插值查找

查字典的直觉

翻字典查 zebra,你不会从中间翻开——你知道 z 在后段,会直接翻到靠后的位置再微调。人脑天然就会按数值比例猜位置。插值查找,就是把这份直觉写成公式。

二分的浪费
有序但均匀分布时,每次都切一半,没利用「值的大小」信息
按比例猜
用目标值在取值区间中的占比,估计它落在向量里的位置
插值公式
按值域比例换算出探测下标,每次朝估计位置跳
适用前提
分布越接近均匀,收敛越快;极端分布会退化
翻字典查 zebra对应 →插值查找

字典里字母靠后的直觉位置,对应按值占比估算的下标

pos=lo+(x−a[lo])⋅hi−loa[hi]−a[lo]pos = lo + (x - a[lo]) \cdot \frac{hi - lo}{a[hi] - a[lo]}
2第 2 页 · 查字典的直觉

折半 vs 插值的猜测策略

两者都只做一次猜测,但猜的位置不同——这直接决定了猜测次数的差异。

折半查找
  • 永远猜正中点 mi = (lo+hi)/2
  • 只看区间长度,不看元素值
  • 最坏 O(logn),且稳定不波动
插值查找
  • 按目标值线性估计 mi(横纵比例换算)
  • 利用有序性猜『应该在哪』
  • 均匀分布时平均 O(loglogn),分布偏斜退化
数据分布均匀且数值跨度大时选插值;分布未知或有偏斜风险时选折半。
3第 3 页 · 折半 vs 插值的猜测策略

插值查找公式与实现

python

用 Python 实现插值查找:公式落成一行代码,循环逼近目标 e。

代码高亮加载中…

第 5 行把 mi = lo + (hi-lo)*(e-a[lo])/(a[hi]-a[lo]) 直接落地;用整除避免浮点,第 4 行防除零,第 10 行的等值判断决定收缩方向。

4第 4 页 · 插值查找公式与实现

手算一轮插值

拿一组具体数字,手算一轮插值查找的猜测与比较。

1
定区间
lo=0,hi=8,目标 70,范围 [0,8]
2
代入公式
mi = 0 + (70-10)×8÷(90-10)=6
3
读出猜测值
向量[6]=70,正是目标
4
比较收敛
相等即返回 6;不等则按 mi 缩小区间
5第 5 页 · 手算一轮插值

完整查找过程

插值查找不是一轮就结束,而是反复收缩区间,直到命中或为空。

1
验证非空
检查 lo < hi 且 e 在 [A[lo], A[hi]] 范围内,否则直接失败
2
按公式猜点
用插值公式算出 mi,这是对目标位置的估计
3
比较命中判定
若 A[mi] == e 则返回 mi,查找成功
4
收缩区间
A[mi] < e 则 lo = mi + 1,否则 hi = mi,排除一段
5
迭代循环
回到第一步,用新区间重新猜测,直至命中或区间为空
6第 6 页 · 完整查找过程

最好与最坏情况

前面手算发现,均匀分布的有序向量里,插值查找几乎一步到位。但真实数据未必均匀,猜测策略对分布的依赖,决定了它的最好与最坏表现相差悬殊。

最好 O(loglogn)
数据近似均匀时,每轮搜索范围呈幂次收缩,迭代次数极少了
最坏 O(n)
分布极度偏斜,比如指数增长,guess 长期贴在边界,逐段扫过去
均匀才是前提
插值公式的线性假设被打破时,性能优势随之消失
查均匀的电话簿对应 →插值查找收敛

页码分布均匀时按比例翻页很准,乱序时只能退回逐页翻

7第 7 页 · 最好与最坏情况

loglogn 是什么概念

横轴是数据规模 n,纵轴是猜测次数。三条曲线分开看:线性几乎竖直上涨,logn 增长缓慢,loglogn 几乎贴地。

图解渲染中…
c2:每次砍半:n 变 logn,即反复开平方,剩余规模缩得极快c3:剩余规模极小时再二分,两重 log 叠加成 loglognc1:一次看一个,n 翻倍猜测次数也翻倍,最慢
8第 8 页 · loglogn 是什么概念

自测:复杂度判断

点击作答

插值查找在什么前提下,平均复杂度才能达到 O(log log n)?

9第 9 页 · 自测:复杂度判断

字宽折半

前面说过,纯插值遇到坏分布会退化到 O(n)。那能不能两头都要?让插值猜得快,又保证最坏不塌——把两种步长混着用。

插值先行
仍按比例猜位置,均匀数据下保持 loglogn 的速度
折半兜底
每轮补一次折半比较,区间必减半,堵住最坏情况
O(√n) 上界
两种步长交替,最坏总代价稳定在根号 n 量级
代价与收益
每轮多一次比较,换来不再依赖数据分布的稳定下界
开车用导航对应 →混合策略

导航给捷径(插值),但每步都强制走一段保险车道(折半)

10第 10 页 · 字宽折半

三种策略综合对比

折半与插值看似只差一个公式,实则依赖的前提完全不同,选错场景会从优雅跌到 O(n)。

折半查找
  • 复杂度稳定 O(logn),无波动
  • 只要求有序,对分布无任何假设
  • 最坏也无害:数据倾斜时仍砍一半
插值查找
  • 均匀分布 O(loglogn),倾斜退化 O(n)
  • 隐含假设:元素近似均匀分布
  • 最坏有害:不均匀时每轮可能只减一
分布未知或数据倾斜时选折半;确认元素均匀分布(如均匀 ID、等差数据)才用插值。
11第 11 页 · 三种策略综合对比

要点收束

  • ✓插值按数值比例猜位置,均匀分布时接近一次命中
  • ✓秩估算公式本质是线性内插,前提是有序
  • ✓最坏退化到 O(n),如指数分布的数据
  • ✓loglogn 增长极慢,百万级约只数次比较
  • ✓实践中常用插值与折半混合,兼顾稳健与速度
延伸主题:从有序向量到散列表查找下界与决策树动态数据的平衡树结构
12第 12 页 · 要点收束

课后思考

先自己想,再看参考答案——答案只是思考的起点。

1插值查找必须要求向量有序,这还不够,为什么数据分布均匀与否会直接决定它的成败?

参考答案想想手算过程:mi 由 hi-lo 按比例推算,均匀分布下猜测才准。分布严重偏斜时,比例估计失真,可能退化回 O(n),等价于每次只排除一个元素。

2在一个包含大量重复元素的有序向量里(如几乎全是同一个值),插值查找还能正常工作吗?该怎么改?

参考答案重复值会让插值点集中在同一区域,区间收缩变慢,甚至可能越界。工程上通常先夹逼边界:命中后向两侧线性收缩,或改用带边界修正的版本保证进度。

3除了数值向量,插值查找的思想还能迁移到什么场景?什么情况下应该果断换回折半?

参考答案凡是能对键做合理线性插值的场景都可用,如按时间戳查日志、浮点均匀采样。但分布未知、数据倾斜或键不可插值时,折半的稳定 O(logn) 更可靠——稳定压倒理论最优。

13第 13 页 · 课后思考
(d5)有序向量:插值查找 · 知识图解