geosmart / geosmart.io

勿助勿忘,深造自得
http://geosmart.github.io/
2 stars 0 forks source link

查找算法-BinarySearch二分查找 #17

Open geosmart opened 5 years ago

geosmart commented 5 years ago

二分查找算法简介

二分查找的复杂度

二分查找的时间复杂度为O(logn),与线性查找的O(n) 相比速度上得到了指数倍提高(x=log2(n),则 n=2^x)。

二分查找算法的局限性

二分查找必须建立在数据已经排好序的基础上才能使用,因此添加数据时必须加到合适的位置,这就需要额外耗费维护数组的时间。 而使用线性查找时,数组中的数据可以是无序的,因此添加数据时也无须顾虑位置,直接把它加在末尾即可,不需要耗费时间。

具体使用哪种查找方法,可以根据查找添加两个操作哪个更为频繁来决定。

算法实现

  @Test
    public void test_bsearch() {
        int a[] = new int[]{1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

        int[] search = new int[]{0, 1, 2, 7, 11};
        for (int s : search) {
            System.out.println(String.format("begin Rsearch[%s]", s));
            int idx = bsearch_recurse(a, 0, a.length - 1, s);
            System.out.println(String.format("end Rsearch[%s],index[%s]", s, idx));
        }

        for (int s : search) {
            System.out.println(String.format("begin Lsearch[%s]", s));
            int idx = bsearch_while(a, s);
            System.out.println(String.format("end Lsearch[%s],index[%s]", s, idx));
        }
    }

    /***
     * 递归实现二分查找
     * @param a 目标数组
     * @param from 开始索引
     * @param to 结果索引
     * @param tar 查找目标
     * @return 目标索引,查不到返回-1
     */
    public int bsearch_recurse(int[] a, int from, int to, int tar) {
        System.out.println(String.format("search from[%s],to[%s]", from, to));
        if (from > to || tar < a[from] || tar > a[to]) {
            return -1;
        } else if (tar == a[from]) {
            return from;
        } else if (tar == a[to]) {
            return to;
        } else {
            int m = (to + from) / 2;
            if (tar > a[m]) {
                return bsearch_recurse(a, m, to, tar);
            } else if (tar < a[m]) {
                return bsearch_recurse(a, from, m, tar);
            } else {
                return m;
            }
        }
    }

    /***
     *循环实现二分查找
     * @param a 目标数组
     * @param tar 查找目标
     * @return 目标索引,查不到返回-1
     */
    public int bsearch_while(int[] a, int tar) {
        int from = 0;
        int to = a.length - 1;
        if (to < 0 || tar < a[from] || tar > a[to]) {
            return -1;
        } else if (tar == a[from]) {
            return from;
        } else if (tar == a[to]) {
            return to;
        } else {
            int m = 0;
            while (from <= to) {
                m = (to + from) / 2;
                System.out.println(String.format("search from[%s],to[%s]", from, to));
                if (tar < a[m]) {
                    to = m - 1;
                } else if (tar > a[m]) {
                    from = m + 1;
                } else {
                    return m;
                }
            }
        }
        return -1;
    }