插值查找原理介绍 :
1)插值查找算法类似于二分查找,不同的是插值查找每次从自适应mid处开始查找。
2)将折半查找中的求mid 索引的公式 , 换成下图中的公式就是插值查找算法的公式 了
-
low 表示左边索引left, high表示右边索引right.
-
key 就是前面我们讲的 findValue(要查找的值)
int mid = low + (high - low) * ( key-a[low] ) / (a[high] - a[low] )
转换成我们的代码公式就是:
int mid = left + (right - left ) * ( findValue - arr[left] ) / ( arr[right] - arr[left] )
package com.lzh.search;
/**
* 插值查找算法(数组是有序的)
*/
public class InsertValueSearch {
public static void main(String[] args) {
int[] arr = new int[100];
for (int i = 0; i < arr.length; i++){
arr[i] = i + 1;
}
//测试
int index = insertSearch(arr,0, arr.length-1, 24);
System.out.println("其下标为:"+index);
}
//插值查找算法方法
public static int insertSearch(int[] arr,int left,int right,int findValue){
//递归结束条件
//findValue > arr[right]要查找的数比最大值还大就可以结束递归了,没必要找
//findValue < arr[left] 要查找的数比最小值还小也没必要找
//同样 findValue > arr[right] || findValue < arr[left] 这两个条件也可以防止越界,因为我们要查找的值是要参与到公式中运算的
if (left > right || findValue > arr[right] || findValue < arr[left]){
return -1;
}
//定义mid的计算方式 int mid = low + (high - low) * ( key-a[low] ) / (a[high] - a[low] )
int mid = left + (right - left) * (findValue - arr[left]) / (arr[right] - arr[left]);
if (findValue > arr[mid]){
//向右进行递归查找
return insertSearch(arr, mid+1, right, findValue);
}else if( findValue < arr[mid]){
//向左递归查找
return insertSearch(arr, left, mid-1, findValue);
}else{
//代表找到了,我们就把这个元素的下标给返回
return mid;
}
}
}
注意:
插值查找注意事项:
1)对于数据量较大,关键字分布比较均匀(元素数值跨越幅度不大的情况)的查找表来说,采用插值查找,速度较快.
2)关键字分布不均匀的情况下,该方法**不一定比折半查找(二分查找)要好