插值查找:
二分查找其效率已经远远高于线性查找,但是我们还可以通过插值查找对二分法查找进行优化。
在二分查找中,mid是(left+right)/2,我i们可以按比例缩小范围,使得我们可以经过更少的次数完成查找。
将mid设置为:left + (right-left)*(value-arr[left])/ (arr[right] - arr[left])。需要注意的是,我们的数组依旧是有序数组,当我们的数组元素全部一样时,此方法不适用。因为除数为0了。
对于数据量大,关键字分布均匀的表来说,插值查找优于二分法查找。如果分布极不均匀,插值查找则不一定优于二分法查找
代码如下:
public static ArrayList< Integer > insertValueSearch(int[] arr, int value, int left, int right) {
if (left > right) {
return new ArrayList< Integer >();
}
int mid = left + (right-left)*(value-arr[left])/ (arr[right] - arr[left]);
//像左递归
if (arr[mid] > value) {
return insertValueSearch(arr, value, 0, mid - 1);
}
//向右递归
else if (arr[mid] < value) {
return insertValueSearch(arr, value, mid + 1, right);
}
//找到了相同的值之后
else {
ArrayList< Integer > list = new ArrayList();
list.add(mid);
int m = mid;
int n = mid;
//向左继续查找
while (n > left && arr[n - 1] == value) {
list.add(n - 1);
n--;
}
//向右继续查找
while (m < right && arr[m + 1] == value) {
list.add(m + 1);
m++;
}
return list;
}
}