什么是插值查找
- 插值查找,有序表的一种查找方式。
- 插值查找基于二分查找,将查找点的选择改进为自适应选择,提高查找效率。
- 插值类似于平常查英文字典的方法,在查一个以字母C开头的英文单词时,决不会用二分查找,从字典的中间一页开始,因为知道它的大概位置是在字典的较前面的部分,因此可以从前面的某处查起,这就是插值查找的基本思想。
- 插值查找除要求查找表是顺序存储的有序表外,还要求数据元素的关键字在查找表中均匀分布,这样,就可以按比例插值。
思路分析
插值查找的实现和二分查找基本一致,唯一的区别就是查找点下标的选择。
其中,key为待查找关键字,low为待查找区间左端,high为待查找区间右端,mid为自适应查找点
- 计算mid
- 如果key==a[mid],返回mid
- 如果key>a[mid],进入右边区间继续查找
- 如果key<a[mid],进入左边区间继续查找
插值查找代码实现
/**
* 插值查找(递归实现)
*
* @param arr 数组
* @param low 待查找区间的左指针
* @param high 待查找区间的右指针
* @param key 待查找的关键字
* @return 查找到的值的下标
*/
public static int insertSearch(int[] arr, int low, int high, int key) {
if (low > high) {
return -1;
}
findCount++;
// 根据待查找值key,计算出
int mid = low + (high - low) * (key - arr[low]) / (arr[high] - arr[low]);
int midVal = arr[mid];
if (key == midVal) {
return mid;
} else if (key > midVal) { // 到右边区域检索
return insertSearch(arr, mid + 1, high, key);
} else { // 到左边区域继续检索
return insertSearch(arr, low, mid - 1, key);
}
}
注意事项
- 插值查找适用于均匀分布的查找表
- 对于分布不均匀的查找表,其不一定适用