JAVA中查找算法-(插值查找算法-动态比例查找)

前奏

前奏:插值查找是一种对折半查找算法的一种升级版,也是一种自适应查找算法(按照对应查找的值,设置对应的比例中间值查找)

思路

核心思路就是,当前元素位置差 left + (right - left) * (findVal - arr[left]) / (arr[right] - arr[left]);
注意:如果left和right都指向了同一个元素的时候就要注意在添加一个判断条件searchElement<arr[left]||searchElement>arr[right])否者会出现算数异常

注意事项

 1:对于数据量较大,各个之间的相依数值跨距(数值差)不是很大,分布均匀(如:100,200,300,400),采用插值查找算法,速度较快
 2:如果与第一条事项相反就用折半查找
 3:动态计算比例注意:如果你查找的值及整个有序数组的长度很如:千万 这时候千万别用int类型 至少要转换成long 类型不然动态计算比例会出现运算异常
 4:循环判断时候注意:searchElement<arr[left]||searchElement>arr[right]),这个递归判断条件非常的重要

图解1

在这里插入图片描述

代码

注意:动态计算超大数据长度的数组时 有可能会出现 栈溢出情况 需谨慎使用

        int[] newArray = new int[60000000];
        for (int i = 0; i < 60000000; i++) {
            newArray[i] =(int) (Math.random() * 60000000);
        }
        Long startTime=System.currentTimeMillis();
        //获取排序后内容信息
        QuickSortDemo.quickSortTheDataDigPit(newArray,0,newArray.length-1);
        Long endTime=System.currentTimeMillis();
        System.out.println(endTime-startTime+"耗时(排序时间)");

        long [] newArray2=new long[newArray.length];
        for(int index=0;index<newArray.length;index++){
            newArray2[index]=newArray[index];
        }


        startTime=System.currentTimeMillis();
        System.out.println(insertValueSearch(newArray2,0,newArray.length-1,59992312)+"==动态比例查找");
        endTime=System.currentTimeMillis();
        System.out.println(endTime-startTime+"耗时(毫秒)");

        startTime=System.currentTimeMillis();
        System.out.println(search(newArray2,59992312)+"==线性查找索引");
        endTime=System.currentTimeMillis();
        System.out.println(endTime-startTime+"耗时(毫秒)");

//注意:searchElement<arr[left]||searchElement>arr[right]),这个递归判断条件非常的重要
    //编写插值查找算法
    //说明:插值查找算法,也要求数组是有序的
    /**
     *
     * @param arr 数组
     * @param left 左边索引
     * @param right 右边索引
     * @param findVal 查找值
     * @return 如果找到,就返回对应的下标,如果没有找到,返回-1
     */
    public static int insertValueSearch(long[] arr, int left, int right, int findVal) {

        //注意:findVal < arr[0]  和  findVal > arr[arr.length - 1] 必须需要
        //否则我们得到的 mid 可能越界
        if (left > right || findVal < arr[0] || findVal > arr[arr.length - 1]) {
            return -1;
        }
        // 求出mid, 自适应
        int mid = new Long(left + (right-left)*(findVal - arr[left])/(arr[right] - arr[left])).intValue();
        long midVal=arr[mid];
        if (findVal > midVal) { // 说明应该向右边递归
            return insertValueSearch(arr, mid + 1, right, findVal);
        } else if (findVal < midVal) { // 说明向左递归查找
            return insertValueSearch(arr, left, mid - 1, findVal);
        } else {
            return mid;
        }
    }

结果

在这里插入图片描述

发布了23 篇原创文章 · 获赞 2 · 访问量 914
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览