插值查找(自适应mid的二分查找)
改进型的二分查找算法(更加适用于连续的数值)
思路
插值查找算法类似于二分查找,不同的是插值查找每次从自适应mid处开始查
将折半查找中的mid索引公式,low改成左边索引left,high表示右边索引right;
key就是要查找的值
3、int midIndex = low +(high-low)*(key-arr[low])/(arr[high]-arr[low])
对应前面的公式:
int midIndex = left + (right - left) * (findVal - arr[left]) / (arr[right]-arr[left])
代码
package G查找;
/**
* @Author Zhou jian
* @Date 2020 ${month} 2020/1/5 0005 17:32
插值查找
*/
public class InsertValueSearch {
public static void main(String[] args) {
int[] arr = new int[100];
for(int i =0;i<100;i++){
arr[i] = i+1;
}
int index = insertValue(arr,0,arr.length-1,100);
System.out.println(index);
}
//编写插值查找算法
//插值查找算法也要求数组是有序的
/**
*
* @param arr 待查找数组
* @param left 左边索引
* @param right 右边索引
* @param findVal 待查找的值
* @return
*/
public static int insertValue(int[] arr,int left,int right,int findVal){
//注意 findVal<arr[0] 和 findVal>arr[arr.length-1]必须需要
//否则我们得到的mid可能越界
if(left>right || findVal<arr[0] || findVal>arr[arr.length-1]){
return -1;
}
//求出mid
int midIndex = left + (right - left) * (findVal - arr[left]) / (arr[right]-arr[left]);
int midValue = arr[midIndex];
if(findVal>midValue){ //向右边递归查找
return insertValue(arr,midIndex+1,right,findVal);
}else if(findVal<midValue){ //向左边递归查找
return insertValue(arr,left,midIndex+1,findVal);
}else{//找到
return midIndex;
}
}
}
小结
- 对于数据量较大,关键字分布比较均匀的查找表来说,采用插值查找,速度较快
- 关键字分布不均匀(跳跃性较大)的情况下,该方法不一定比折半要好