7.4 插值查找
7.4.1 二分查找算法的弊端
每次需要将待查找数据和数组的中间元素进行比较,然后进行左边和右边部分的查找。当然,相比于顺序查找,在数据量较大的时候,折半查找具有较高的效率。当然,不可避免的,当出现极端情况时,二分查找依然需要进行叫多次比较查找。譬如,对于一个待查找数组,位于整个有序数组的最左边或者最右边,二分查找方法还是需要从中间依次进行比较查找。
7.4.2 插值查找算法介绍
-
插值查找算法类似于二分查找,不同的是插值查找每次从自适应mid处开始查找;(自适应即mid的值跟待查找的值存在一种关系,mid值再进行自适应的变化,使得更加快速的趋近于待查找的值)
-
在二分查找中,mid的求值方法为:
在折半查找中,将求mid 索引的公式修改为:
7.4.3 代码实现
package com.kevin.search;
/**
* @author : kevin ding
* @date : 2022/3/11 22:52
* @description : 插值查找算法
*/
public class InsertSearchDemo {
public static void main(String[] args) {
int[] array = {
11, 12, 33, 37, 42, 75, 88, 174, 189, 325, 456};
int targetValue = 11;
int valueIndex= insertValueSearch(array, 0, array.length - 1, targetValue);
if(valueIndex == -1){
System.out.println("没有找到....");
}else {
System.out.println("找到了," + targetValue + "在array中的索引位置为:" + valueIndex);
}
}
public static int insertValueSearch(int[] array, int left, int right, int targetVal){
System.out.println("查找次数..");
// 判断是否越界
if(left > right || targetVal < array[0] || targetVal > array[array.length-1]){
return -1;
}
// mid的值为自适应值
int mid = left + (right - left) * (targetVal - array[left]) / (array[right] - array[left]);
int midValue = array[mid];
if(targetVal > midValue){
// 向右递归查找
return insertValueSearch(array, mid+1, right, targetVal);
}else if (targetVal < midValue){
// 向左递归查找
return insertValueSearch(array, left, mid-1, targetVal);
}else {
// 找到了位置,mid
return mid;
}
}
}
7.4.4结果对比
当分别对程序中的数组 {11, 12, 33, 37, 42, 75, 88, 174, 189, 325, 456}查找11时,二分查找的次数及结果为,总共查找了3次才找到:
而插值查找算法查找的结果为,只查找了一次就找到了:
总结
- 对于数据量较大,关键字分布比较均匀的查找表来说,采用插值查找速度较快。
-元素分布不均匀的情况下,插值查找方法不一定比折半查找要好。