插值查找

入门

比二分更"按值猜位置",理解公式估计过程是关键。

定义数组和目标值

可视化演示开发中

插值查找 的交互式动画即将上线,敬请期待。

// 源代码
1int interpolationSearch(int arr[], int n, int target) {
2    int left = 0, right = n - 1;
3    while (left <= right && target >= arr[left] && target <= arr[right]) {
4        if (arr[left] == arr[right]) {
5            return arr[left] == target ? left : -1;
6        }
7        int pos = left + (target - arr[left]) * (right - left) / (arr[right] - arr[left]);
8        if (arr[pos] == target) return pos;
9        if (arr[pos] < target) left = pos + 1;
10        else right = pos - 1;
11    }
12    return -1;
13}

复杂度分析

时间 O(log log n)
空间 O(1)
最优 O(1)
最坏 O(n)

算法讲解

插值查找也要求数组升序,但它不固定检查中点,而是根据目标值在当前值域中的相对位置估算 probe 点。

如果数组分布比较均匀,probe 往往会直接落在离答案更近的位置,因此平均表现可能优于普通二分。

这也是为什么页面里会特别高亮左右边界和值域范围,因为公式正是基于这两个端点推算出来的。

当数据分布很不均匀时,公式猜测可能失准,算法性能也可能明显退化。

因此插值查找最适合"数值连续、分布接近均匀"的有序表,而不适合跨度极不稳定的数据。

平均时间复杂度常写作 O(log log n),最坏情况下仍可能退化到 O(n)。