1.初次相识
插值查找(interpolation search)是一种根据待查找关键字在有序数组中的大致位置决定查找范围的查找算法。插值查找与二分查找类似,区别在于插值查找对于待查找关键字在数组中的位置进行估计,从而更精准地定位到待查找关键字所在位置。插值查找的时间复杂度为O(log(log(n))),在数据量较大、关键字分布较均匀的情况下,查找效率较高。
2.原理解析
- 1.插值查找算法类似于二分查找,不同的是插值查找每次从自适应mid处开始查找。
- 2.公式:int middle = left + (right-left)* (value-arr[lefr])/ (arr[right]-arr[left]).
left:数组左边索引下标
rigth:数组最右边索引下标
value:要查找的数
3.代码堆积
public static List<Integer> insertSearch(int[] arr, int left, int right, int value) {
if (left > right || value < arr[0] || value > arr[arr.length - 1]) {
return new ArrayList<>();
}
//求中间值
int middle = left + (right - left) * (value - arr[left]) / (arr[right] - arr[left]);
int middleVale = arr[middle];
if (value > middleVale) {
return insertSearch(arr, middle + 1, right, value);
} else if (value < middleVale) {
return insertSearch(arr, left, middle - 1, value);
} else {
List<Integer> list = new ArrayList<>();
int temp = middle - 1;
while (true) {
if (temp < 0 || arr[temp] != value) {
break;
}
list.add(temp);
temp--;
}
list.add(middle);
temp = middle + 1;
while (true) {
if (temp > arr.length - 1 || arr[temp] != value) {
break;
}
list.add(temp);
temp++;
}
return list;
}
}
4.测试
public static void main(String[] args) {
int[] arr = new int[]{1,2,3,4,5,6,6};
List<Integer> list = insertSearch(arr, 0, arr.length - 1, 6);
System.out.println("查找数字的下标有:"+list);
}
5.总结
插值查找与二分法法查找基本相似,只是运用了一个小算法,自适应找中间值middle
- int middle = left + (right-left)* (value-arr[lefr])/ (arr[right]-arr[left]).