查找算法:插值查找

Searching Algorithms: Interpolation Search

. 前言

该博客用于本弱鸡复习巩固,打牢基础,还望各大佬不吝赐教。

. 基本思路

插值查找是二分查找的改进版
它是根据要查找的关键字 key 与查找表中的最大最小记录的关键字比较后的查找方法,
其核心在于差值的计算公式 (key-arr[low]) / (arr[high]-arr[Low])

现在有个新问题,为什么每次要折半而不是折四分之一或者更多呢?
打个比方,在英文词典里查“apple”,你会下意识翻开前面的书页,而如果你要查“zoo”,很显然,你肯定不会从中间开始查起,而是有一定目的地往后翻。
同样地,比如在取值范围 0-10000 之间100个元素从小到大均匀分布的数组中查找 5 ,我们自然会考虑从数组角标较小的开始查找。
———————————————————————————《大话数据结构》


The Interpolation Search is an improvement over Binary Search for instances,where the values in a sorted array are uniformly distributed.
Binary Search always goes to the middle element to check.
On the other hand,interpolation search may go to different locations according to the value of the key being searched.For example, if the value of the key is closer to the last element,interpolation search is likely to start search toward the end side.
——————————————————www.geeksforgeeks.org/interpolation-search/

. 图片示例

插值查找
插值查找

. 算法复杂度分析

平均为O(logn)
对于数组较大,关键字分布比较均匀,插值查找性能比二分查找性能好得多。
但若数组关键字大小分布极不均匀,插值查找未必合适。

. 代码实现

 1import java.util.Arrays;
2/**
3 * Interpolation Search 插值查找 二分查找改进版
4 * 比如在 1-10000 均匀分布的元素中查找 5 ,明显用原二分法查找会有很多次无意义的二分
5 * 不如直接从角标较小的地方开始二分查找
6 * 根据要查找的关键字 key 与查找表中的最大最小记录的关键字比较后的查找方法
7 * 其核心在于差值的计算公式 (key-arr[low]) / (arr[high]-arr[Low])
8 * 
9 * The Interpolation Search is an improvement over Binary Search for 
10 * instances,
11 * where the values in a sorted array are uniformly distributed.
12 * Binary Search always goes to the middle element to check.
13 * On the other hand,
14 * interpolation search may go to different locations according to the value of the key being searched.
15 * For example, if the value of the key is closer to the last element,
16 * interpolation search is likely to start search toward the end side.
17 * 
18 * 时间复杂度 O(logn)
19 * 
20 * 对于数组较大,关键字分布比较均匀,插值查找性能比二分查找性能好得多
21 * 但若数组关键字大小分布极不均匀,插值查找未必合适
22 */

23public class InterpolationSearch {
24
25    public static void main(String[] args) {
26
27        int[] a = new int[]{0123456789};
28        System.out.println(Arrays.toString(a));
29
30        int key = 99;
31
32        int index = binarySearch(key, a);
33
34        System.out.println(index);
35    }
36
37    public static int binarySearch(int key, int[] a) {
38        int mid;
39        int start = 0;
40        int end = a.length - 1;
41        //保证角标不越界,key不在数组范围内则返回-1
42        //否则不判定的话 key 过大 导致 mid 过大从而角标越界
43        while (start <= end && key >= a[start] && key <= a[end]) {
44            //插值
45            mid = start + (end - start) * (key - a[start]) / (a[end] - a[start]);
46            if (key < a[mid]) {
47                end = mid - 1;
48            } else if (key > a[mid]) {
49                start = mid + 1;
50            } else {
51                return mid;
52            }
53        }
54        return -1;
55    }
56}

. 参考