差值查找算法
思想
基于二分查找算法,将查找点的选择改进为自适应选择,可以提高查找效率。如果要在取值范围1 ~ 10000 之间 100 个元素从小到大均匀分布的数组中查找5, 我们自然会考虑从数组下标较小的开始查找。关键点在于计算出查找点位置,二分查找是mid=(high-low)/2,简单暴力傻瓜式,差值查找算法的查找点计算方式为:
mid=low+(key-a[low])/(a[high]-a[low])*(high-low),
该公式的推导过程:(类似于黄金分割)
有公式可知,当比例大于1就不会存在查找列表中;
这个比例能帮助我们确定更精确的范围,减少查询次数。
应用场景:
必须基于有序的查找序列,对于目标数组量比较大,并且按照一定走势增长的,这样插值查找算法的效率是比较快的
java实现
/**
* 循环实现差值查找算法arr 已排好序的数组x 需要查找的数-1 无法查到数据
*/
public static int differenceSearch(int[] arr, int x) {
int low = 0;
int high = arr.length - 1;
while (low <= high) {
int mid = low+(x-arr[low])/(arr[high]-arr[low])*(high-low);
if (x == arr[mid]) {
return mid;
} else if (x < arr[mid]) {
high = mid - 1;
} else {
low = mid + 1;
}
}
return -1;
}
/**
* 递归实现差值查找
*/
public static int differenceSearch(int[] array, int queryData, int startIndex, int endIndex) {
int midIndex = startIndex+(queryData-array[startIndex])/(array[endIndex]-array[startIndex])*(endIndex-startIndex);
if (queryData < array[startIndex] || queryData > array[endIndex] || startIndex > endIndex) {
return -1;
}
if (queryData < array[midIndex]) {
return binarySearch(array, queryData, startIndex, midIndex - 1);
} else if (queryData > array[midIndex]) {
return binarySearch(array, queryData, midIndex + 1, endIndex);
} else {
return midIndex;
}
}