二分查找算法(递归与非递归)与插值查找算法

二分查找算法

二分查找算法不作过多的文字说明,请看代码和注释
使用递归查找

public class BinarySearch {

    public static void main(String[] args) {
        int[] array = {3,4,6,7,12,34,56,78};
        int index = search(array, 0, array.length - 1, 78);
        if (index > 0) {
            System.out.println("找到要查找的值得下标:" + index);
        }else {
            System.out.println("没有找到要查找的值");
        }
    }

    /**
     * 二分查找的数组必须是有序,该方法规定算组以升序排序
     * @param arry 查找 值 的 目标数组
     * @param left 查找开始的左索引
     * @param right 查找的右索引
     * @param val 查找的目标值
     */
    public static int search(int[]  arry, int left, int right, int val) {
        // 递归退出的条件,说明没有找到要数
        if (left > right) {
            return -1;
        }
        int mid = (left + right) / 2;
        if (arry[mid] > val) {
            // 向左递归
            return search(arry, left, mid - 1, val);
        } else if (arry[mid] < val) {
            // 向右递归
            return search(arry,mid + 1, right, val);
        }else {
            // arry[mid] = val
            // 代码走到这说明已经找到
            return mid;
        }
    }
}

使用非递归的二分查找

public class BinarySearch {
    public static void main(String[] args) {
        int[] arr = {1,3, 8, 10, 11, 67, 100};
        int search = search(arr, 101);
        System.out.println("找到了,下标:" + search);
    }

    /**
     * 非递归的 二分查找算法
     * @param arr
     * @param targertVal
     * @return
     */
    public static int search(int[] arr, int targertVal) {
        if (arr == null || arr.length == 0) {
            return -1;
        }
        // 左边索引
        int leftIndex = 0;
        // 右边索引
        int rightIndex = arr.length - 1;

        while (leftIndex <= rightIndex) {
            int midIndex = (leftIndex + rightIndex)/2;
            if (arr[midIndex] == targertVal) {
                return midIndex;
            } else if (arr[midIndex] > targertVal) {
                rightIndex = midIndex - 1;
            }else {
                leftIndex = midIndex + 1;
            }
        }
        // 循环结束,代码走到这,则没有找到
        return -1;
    }
}

插值查找算法

插值查找原理介绍:

  1. 插值查找算法类似于二分查找,不同的是插值查找每次从自适应mid处开始查找。

  2. 将折半查找中的求mid 索引的公式 , low 表示左边索引left, high表示右边索引right.key 就是前面我们讲的 findVal
    在这里插入图片描述

  3. int mid = low + (high - low) * (key - arr[low]) / (arr[high] - arr[low]) ;/插值索引/对应前面的代码公式:int mid = left + (right – left) * (findVal – arr[left]) / (arr[right] – arr[left])

代码示例

public class BinarySearch {

    public static void main(String[] args) {
        int[] array = {3,4,6,7,12,34,56,78};
        int index = insertValueSearch(array, 0, array.length - 1, 78);
        if (index > 0) {
            System.out.println("找到要查找的值得下标:" + index);
        }else {
            System.out.println("没有找到要查找的值");
        }
    }

    /**
     * 二分查找的数组必须是有序,该方法规定算组以升序排序
     * @param arr 查找 值 的 目标数组
     * @param left 查找开始的左索引
     * @param right 查找的右索引
     * @param findVal 查找的目标值
     */
    public static int insertValueSearch(int[]  arr, int left, int right, int findVal) {
        System.out.println("##########################");
        // 递归退出的条件,说明没有找到要数
        if (left > right || findVal < arr[0] || findVal > arr[arr.length - 1]) {
            return -1;
        }
        int mid = left + (right - left) * (findVal - arr[left]) / (arr[right] - arr[left]);
        if (arr[mid] > findVal) {
            // 向左递归
            return insertValueSearch(arr, left, mid - 1, findVal);
        } else if (arr[mid] < findVal) {
            // 向右递归
            return insertValueSearch(arr,mid + 1, right, findVal);
        }else {
            // arry[mid] = val
            // 代码走到这说明已经找到
            return mid;
        }
    }
}

运行结果:

##########################
找到要查找的值得下标:7

从结果可以看出 ,通过插值查找可以减少查找的次数(即减少递归调用的次数),因而有较高的效率。

总结

  1. 对于数据量较大,关键字分布比较均匀的查找表来说,采用插值查找, 速度较快.
  2. 关键字分布不均匀的情况下,该方法不一定比折半查找要好
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值