实现一个不用除法的二分查找(移位运算符,斐波那契查找)

这边提供两种方案:

1,常规二分查找里面,除法的作用只为了除以2,这个等价于右移1位,故直接更改mid的计算如下:

public static int rank(int key, int[] a) { // 数组必须是有序的
        int lo = 0;
        int hi = a.length - 1;
        while (lo <= hi) { // 被查找的键要么不存在,要么必然存在于a[lo..hi] 之中
            int mid = lo + ((hi - lo) >> 1);// 右移一位
            if (key < a[mid]) {
                hi = mid - 1;
            } else if (key > a[mid]) {
                lo = mid + 1;
            } else return mid;
        }
        return -1;
    }

2,采用斐波那契查找,思路是将二分的mid值定为黄金分割点,数组长度为f(n)-1,左边为f(n-2)-1,中间1,右边为f(n-1)-1,不清楚的可以看我之前的那期斐波那契数,或者百度一下,这边是直接提供解决方案:

public static int fSearch(int[] arr, int key) {
        int left = 0;
        int right = arr.length - 1;
        int[] f = fib();
        int k = 0;
        int mid = 0;
        while (arr.length > f[k] - 1) {
            k++;
        }
        int[] tmp = Arrays.copyOf(arr, f[k]);
        for (int i = right + 1; i < tmp.length; i++) {
            tmp[i] = tmp[right];
        }
        while (left <= right) {
            mid = left + (f[k - 1] - 1);
            if (key < tmp[mid]) {
                right = mid - 1;
                k--;
            } else if (key > tmp[mid]) {
                left = mid + 1;
                k -= 2;
            } else if (mid > arr.length - 1) {
                return arr.length - 1;
            } else return mid;
        }
        return -1;

    }
    public static int[] fib() {
        int[] f = new int[20];
        f[0] = 1;
        f[1] = 1;
        for (int i = 2; i < MaxSize; i++) {
            f[i] = f[i - 1] + f[i - 2];
        }
        return f;
    }

 

posted @ 2020-05-07 10:24  junlancer  阅读(436)  评论(0编辑  收藏  举报