查找-插值查找

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

源码:https://github.com/sunrui849/selectAlgorithm

目录:顺序查找

二分查找

插值查找

斐波那契查找

分块查找

哈希查找

二叉树查找

红黑树查找

插值查找

算法简介

    插值查找是根据要查找的关键字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();
    }

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值