zoukankan      html  css  js  c++  java
  • 二分搜索法(转载自vanezkw)

    二分查找算法java实现

    今天看了一下JDK里面的二分法是实现,觉得有点小问题。二分法的实现有多种今天就给大家分享两种。一种是递归方式的,一种是非递归方式的。先来看看一些基础的东西。

    1、算法概念。

    二分查找算法也称为折半搜索、二分搜索,是一种在有序数组中查找某一特定元素的搜索算法。请注意这种算法是建立在有序数组基础上的。

    2、算法思想。

    ①搜素过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜素过程结束;

    ②如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较。

    ③如果在某一步骤数组为空,则代表找不到。

    这种搜索算法每一次比较都使搜索范围缩小一半。

    3、实现思路。

    ①找出位于数组中间的值,并存放在一个变量中(为了下面的说明,变量暂时命名为temp);

    ②需要找到的key和temp进行比较;

    ③如果key值大于temp,则把数组中间位置作为下一次计算的起点;重复① ②。

    ④如果key值小于temp,则把数组中间位置作为下一次计算的终点;重复① ② ③。

    ⑤如果key值等于temp,则返回数组下标,完成查找。

    4、实现代码。

    /**
         * description : 二分查找。
         * @autor kwzhang
         * modify :2012-6-29
         *
         * @param <E>
         * @param array 需要查找的有序数组
         * @param from 起始下标
         * @param to 终止下标
         * @param key 需要查找的关键字
         * @return
         * @throws Exception
         */
        public static <E extends Comparable<E>> int binarySearch(E[] array, int from, int to, E key) throws Exception {
            if (from < 0 || to < 0) {
                throw new IllegalArgumentException("params from & length must larger than 0 .");
            }
            if (from <= to) {
                int middle = (from >>> 1) + (to >>> 1); // 右移即除2
                E temp = array[middle];
                if (temp.compareTo(key) > 0) {
                    to = middle - 1;
                } else if (temp.compareTo(key) < 0) {
                    from = middle + 1;
                } else {
                    return middle;
                }
            }
            return binarySearch(array, from, to, key);
        }

    5、测试demo很简单,这里就不写了。

     

    上面这种实现是通过递归的方式,各人觉得之类的问题用递归比较好理解,而且过程简单。

    下面再来看看非递归的方式如何实现。在JDK里面正好有实现,在此就直接贴上Arrays里面的代码。为了简单起见,我们就只看看int参数的方法:

    private static int binarySearch0(int[] a, int fromIndex, int toIndex, int key) {
        int low = fromIndex;
        int high = toIndex - 1;
        while (low <= high) {
            int mid = (low + high) >>> 1;
            int midVal = a[mid];
            if (midVal < key)
            low = mid + 1;
            else if (midVal > key)
            high = mid - 1;
            else
            return mid; // key found
        }
        return -(low + 1);  // key not found.
        } 

    上面这方法是我直接中SDK里面拷的(我可没有改动过)。之所以强调这个方法是因为此方法个人觉得有问题的(相信你也会觉得)。

    当key为数组a中的最后一个值时,那么就会找不到(不明白sun公司当初是怎么想的)。个人觉得需要把 int high = toIndex - 1; 改成 int high = toIndex;  

  • 相关阅读:
    LeetCode 123. Best Time to Buy and Sell Stock III (stock problem)
    精帖转载(关于stock problem)
    LeetCode 122. Best Time to Buy and Sell Stock II (stock problem)
    LeetCode 121. Best Time to Buy and Sell Stock (stock problem)
    LeetCode 120. Triangle
    基于docker 搭建Elasticsearch5.6.4 分布式集群
    从零开始构建一个centos+jdk7+tomcat7的docker镜像文件
    Harbor实现容器镜像仓库的管理和运维
    docker中制作自己的JDK+tomcat镜像
    docker镜像制作---jdk7+tomcat7基础镜像
  • 原文地址:https://www.cnblogs.com/shadowduke/p/4864464.html
Copyright © 2011-2022 走看看