You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何插值搜索计算位置与线性搜索一致?代码是否有误?

插值搜索代码为何退化为线性搜索?

问题出在插值位置计算的优先级与顺序错误,导致公式完全失效,最终退化为线性遍历。

原代码中的pos计算逻辑:

pos = lo + ((hi - lo) // (ar[hi] - ar[lo]) * (x - ar[lo]))

在Python中,整数除法//和乘法*优先级相同,运算顺序为从左到右。以第一次调用为例:

  • hi-lo = 14,ar[hi]-ar[lo] = 47-10=37,14//37结果为0
  • 0乘以x-ar[lo] = 18-10=8,结果仍为0
  • 最终pos=0+0=0

每次递归时,(hi-lo)//(ar[hi]-ar[lo])的结果都是0(数组元素间隔小,区间长度除以值范围的商小于1,整数除法后取整为0),导致pos始终等于当前lo。又因为ar[pos]<x,递归调用pos+1,最终变成了逐个递增的线性搜索。

正确的插值搜索公式应先计算分子部分(x-ar[lo])*(hi-lo),再除以分母(ar[hi]-ar[lo]),修正后的代码:

def interpolation_search(ar:list, lo:int, hi:int, x:int):                                
    if (lo <= hi and x >= ar[lo] and x <= ar[hi]):                                       
        # 调整计算顺序,先算乘法再做整数除法
        pos = lo + ((x - ar[lo]) * (hi - lo)) // (ar[hi] - ar[lo])                       
                                                                                           
        print(pos)                                                                       
                                                                                             
        if ar[pos] == x:                                                                 
            return pos                                                                   
                                                                                           
        if ar[pos] < x:                                                                  
            return interpolation_search(ar, pos + 1, hi, x)                              
                                                                                             
        if ar[pos] > x:                                                                  
            return interpolation_search(ar, lo, pos - 1, x)                              
                                                                                             
    return -1 
    
if __name__ == '__main__':                                                               
    v = 18                                                                                                                                                 
    ar = [10, 12, 13, 16, 18, 19, 20, 21, 22, 23, 24, 33, 35, 42, 47]                                                           
    assert(interpolation_search(ar, 0, len(ar)-1, v) == 4) 

修正后运行代码,print(pos)会直接输出4,一次定位到目标值,符合插值搜索的预期。

内容的提问来源于stack exchange,提问作者user23145140

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 14:12:25