插值查找算法:
1)插值查找算法类似于二分查找,不同的是插值查找每次从自适应mid处开始查找
2)将折半查找中的求mid索引的公式进行修改:
原:mid = (low + high) / 2 = low + (high - low) / 2
修改后:mid = low + (key - arr[low]) / (arr[high] - arr[low]) * (high - low)
其中low表示左索引left,high表示右索引right,key表示要查找的值,arr是数组
3)int mid = low + (key - arr[low]) / (arr[high] - arr[low]) * (high - low)
用一个1–100的数组来举例说明
Java代码实现:
public class InsertValueSearch {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] arr = new int[100];
for(int i = 0; i < 100; i++) {
arr[i] = i + 1;
}
int index = insertValueSearch(arr, 0, arr.length-1, 100);
System.out.println("该数据对应的下标为:"+index);
}
//编写插值查找算法
//同样要求数组是有序的
/**
*
* @param arr 数组
* @param left 左边索引
* @param right 右边索引
* @param findVal 需要查找的值
* @return 如果找到则返回对应的下标,如果没有则返回-1
*/
public static int insertValueSearch(int[] arr,int left,int right,int findVal) {
//防止mid越界
if(left > right || findVal < arr[0] || findVal > arr[arr.length-1]) {
return -1;
}
//求出mid
int mid = left + (right - left) * (findVal - arr[left]) / (arr[right]- arr[left]);
int midVal = arr[mid];
if(findVal > midVal) {
//说明应该向右递归
return insertValueSearch(arr, mid+1, right, findVal);
}else if(findVal < midVal) {
//说明应该向右递归
return insertValueSearch(arr, left, mid-1, findVal);
}else {
return mid;
}
}
}
插值查找注意事项:
1)对于数据量较大,关键字分布比较均匀的查找表来说,采用插值查找,速度较快。
2)关键字分布不均匀的情况下,该方法不一定比折半查找要好。