Java算法--二分查找算法

Posted Z && Y

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java算法--二分查找算法相关的知识,希望对你有一定的参考价值。

1. 二分查找算法


1.1 引言

现在假设你登录QQ。当你这样做时,QQ必须核实你是否有其网站的账户,因此必须在其数据
库中查找你的QQ账号。如果你的用户名为6585526229,QQ可从以1打头的部分开始
查找,但更合乎逻辑的做法是从中间开始查找。

这是一个查找问题,可使用同一种算法来解决问题,这种算法就是二分查找。

1.1.1 简单查找

下面的示例说明了二分查找的工作原理。我随便想一个1~100的数字。
在这里插入图片描述
你的目标是以最少的次数猜到这个数字。你每次猜测后,我会说小了、大了或对了。
假设你从1开始依次往上猜,猜测过程会是这样。
在这里插入图片描述
这是简单查找,更准确的说法是傻找。每次猜测都只能排除一个数字。如果我想的数字是99,你得猜99次才能猜到


1.1.2 更佳的查找方式

下面是一种更佳的猜法。从 50 开始。
在这里插入图片描述
在这里插入图片描述

不管我心里想的是哪个数字,你在7次之内都能猜到,因为每次
猜测都将排除很多数字


1.2 二分查找法

二分查找是一种算法,其输入是一个有序的元素列表(这是折半查找的前提,没有排序的序列不能使用折半查找。 折半查找:取序列中间的值与查找值比较,如果查找值大,则查找值在序列后半部,继续在 后半部折半查找;如果等同查找值,则找到;否则在前半部。)。如果要查找的元素包含在列表中,二分查找返回其位置;否则返回-1。


1.3 二分查找Java代码实现


1.3.1 一般的二分查找算法

    /**
     * MethodName: commonBinarySearch
     * Description: 二分查找的一般算法
     *
     * @return int
     * @date 2021/7/2 21:34
     * @params: [arr, key] arr查找的数组 key是具体查找的值
     * @author Tianjiao
     */
    public static int commonBinarySearch(int[] arr, int key) {
        int low = 0;
        int high = arr.length - 1;
        int middle;         //定义middle
        if (key < arr[low] || key > arr[high]) {
            return -1;
        }
        while (low <= high) {
            middle = (low + high) / 2;
            if (arr[middle] > key) {
                //比关键字大则关键字在左区域
                high = middle - 1;
            } else if (arr[middle] < key) {
                //比关键字小则关键字在右区域
                low = middle + 1;
            } else {
                return middle;
            }
        }
        return -1;      //最后仍然没有找到,则返回-1
    }

测试代码:

    public static void main(String[] args) {
        int[] arr = {1, 4, 8, 16, 45, 48, 78};
        System.out.println(commonBinarySearch(arr, 4));
    }

在这里插入图片描述


1.3.2 使用递归进行二分查找

    /**
     * MethodName: recursionBinarySearch
     * Description: 二分查找的递归算法
     *
     * @return int
     * @date 2021/7/2 21:42
     * @params: [arr, key, low, high] arr查找的数组 key是具体查找的值  low是查找的下限 high是查找的上限
     * @author Tianjiao
     */
    public static int recursionBinarySearch(int[] arr, int key, int low, int high) {
        if (key < arr[low] || key > arr[high] || low > high) {
            return -1;
        }
        int middle = (low + high) / 2;          //初始中间位置
        if (arr[middle] > key) {
            //比关键字大则关键字在左区域
            return recursionBinarySearch(arr, key, low, middle - 1);
        } else if (arr[middle] < key) {
            //比关键字小则关键字在右区域
            return recursionBinarySearch(arr, key, middle + 1, high);
        } else {
            return middle;
        }
    }

测试代码:
在这里插入图片描述


1.4 二分查找的运行时间

一般而言,应选择效率最高的算法,以最大限度地减少运行时间或占用空间。

  • 回到前面的二分查找。使用它可节省多少时间呢?简单查找逐个地检查数字,如果列表包含100个数字,最多需要猜100次。如果列表包含40亿个数字,最多需要猜40亿次。换言之,最多需要猜测的次数与列表长度相同,这被称为线性时间(linear time)。
  • 二分查找则不同。如果列表包含100个元素,最多要猜7次;如果列表包含40亿个数字,最多需猜32次。厉害吧?二分查找的运行时间为对数时间(或log时间)。下表总结了我们发现的情况。
    在这里插入图片描述


以上是关于Java算法--二分查找算法的主要内容,如果未能解决你的问题,请参考以下文章

Java学习之二分查找算法

[Algorithm]二分插值斐波那契查找算法 Java 代码实现

[Algorithm]二分插值斐波那契查找算法 Java 代码实现

java泛型 二分查找

二分算法(java超详细)

Day589.二分查找(非递归) -数据结构和算法Java