二分查找算法java实现

 

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

一、算法概念。算法

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

二、算法思想。数组

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

②若是某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,并且跟开始同样从中间元素开始比较。测试

③若是在某一步骤数组为空,则表明找不到。spa

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

三、实现思路。blog

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

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

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

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

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

四、实现代码。

复制代码
/**
     * 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);
    }
复制代码

五、测试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;  

 

这个算法到此为止。欢迎讨论交流。

相关文章
相关标签/搜索