码迷,mamicode.com
首页 > 其他好文 > 详细

插值查找

时间:2019-01-01 17:17:11      阅读:177      评论:0      收藏:0      [点我收藏+]

标签:length   复杂度   时间   改进   app   次数   ret   英文   基于   

在介绍插值查找之前,首先考虑一个问题,为什么二分查找算法中一定是折半,而不是折四分之一,或者折更多呢?
打个比方,在英文字典里面查“apple”,你下意识翻开字典是翻前面的书页还是后面的书页呢?如果再查“zoo”,又该怎么查呢?很显然,这两个单词绝对不会从中间开始查起,而是有一定目的地从前或从后开始查;
同样地,比如要在取值范围1~10000之间100个元素从小到大均匀分布的数组中查找5,我们自然会考虑从数组下标较小的开始查找;
经过以上分析,二分查找这种查找方式,不是自适应的(也就是傻瓜式的),二分查找中查找点计算如下:
mid = (low + high)/2 = low + 1/2 * (high - low);
通过类比,可以将查找的点改进为如下:
mid = low + ((key - arr[low])/(arr[high] - arr[low])) * (high - low);
也就是将上述的比例参数1/2改进为自适应的,根据关键字在整个有序表中所处的位置,让mid值的变化更靠近关键字key,这样也就间接地减少了比较次数;

基本思想:基于二分查找算法,将查找点的选择改进为自适应选择,可以提高查找效率。当然,插值查找也属于有序查找。

注:对于表长较大,而关键字分布又比较均匀的查找表来说,插值查找算法的平均性能比二分查找算法要好得多。

复杂度分析:时间复杂度O(log2^(log2^n))。

代码示例:
public class Test {

    public static void main(String[] args) {
        
        int[] arr = {1, 2, 3, 6, 8, 9};
        System.out.println(binary_Search(arr, 8));
    }
    public static int binary_Search(int[] arr, int num) {
        int high = arr.length - 1;
        int low = 0;
        int mid;
        while(low < high) {
            mid = low + ((num - arr[low])/(arr[high] - arr[low])) * (high - low);
            if(arr[mid] > num) {
                high = mid - 1;
            } else if (arr[mid] < num) {
                low = mid + 1;
            } else {
                return mid;
            }
        }
        return -1;
    }
}

插值查找

标签:length   复杂度   时间   改进   app   次数   ret   英文   基于   

原文地址:https://www.cnblogs.com/yuanfei1110111/p/10205065.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!