欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

查找-插值查找

程序员文章站 2022-05-17 21:36:18
...

参考:https://www.cnblogs.com/lsqin/p/9342929.html

插值查找

算法简介

    插值查找是根据要查找的关键字key与查找表中最大最小记录的关键字比较后的 查找方法,其核心就在于插值的计算公式 (key-a[low])/(a[high]-a[low])*(high-low)。
    时间复杂度o(logn)但对于表长较大而关键字分布比较均匀的查找表来说,效率较高。

算法思想

    基于二分查找算法,将查找点的选择改进为自适应选择,可以提高查找效率。当然,差值查找也属于有序查找。
    注:对于表长较大,而关键字分布又比较均匀的查找表来说,插值查找算法的平均性能比折半查找要好的多。反之,数组中如果分布非常不均匀,那么插值查找未必是很合适的选择。注意处理当a[high]-a[low]时为0的情况

复杂度分析 

    时间复杂性:如果元素均匀分布,则O(log log n)),在最坏的情况下可能需要 O(n)。
    空间复杂度:O(1)。

算法实现

/**
     * 非递归写法
     * ************注意java实现时,要使用除法保留小数,否则每次middle都只加一*************
     * @param list
     * @param selectValue
     * @return
     */
    private static int select(List<Integer> list, int selectValue) {
        if (list == null || list.isEmpty()){
            return -1;
        }
        int start = 0;
        int end = list.size() - 1;

        while (end > start){
            int middle = start + (int)Math.floor(division((selectValue - list.get(start)),(list.get(end) - list.get(start))) * (end - start));
            if (list.get(middle) > selectValue){
                end = middle - 1;
            } else if ((list.get(middle) < selectValue)){
                start = middle + 1;
            } else {
                return middle;
            }
        }
        return -1;
    }

    /**
     * 除法,保留两位小数
     */
    private static double division(int value1,int value2) {
        if (value2 == 0){
            return 0;
        }
        BigDecimal v1 = new BigDecimal(value1);
        BigDecimal v2 = new BigDecimal(value2);
        return v1.divide(v2,2, RoundingMode.HALF_UP).doubleValue();
    }

 

相关标签: 插值查找 java