斐波那契查找算法

97 阅读1分钟

基本思想

将一个长度为F(n)数组看做前后两半,前面一半长度是F(n-1),后面一半的长度是F(n-1) 。正是这个想法将斐波那契数列和数组联系到一起,也是后面分析的基础:

v2-f7dd94026668e17bdec3633ff6b4cea8_b

原理分析

整个过程可以分为:

  • 构建斐波那契数列
  • 然后计算数组长度对应的斐波那契数列元素,如果没有找到的话,就找数列中第一个大于数组长度的值
  • 对数组按照找到的数值进行填充
  • 然后将长度为F(n)的数组分割为F(n-1)和F(n-2)两个部分,判断中间值
  • 如果中间值大于目标值,则要在F(n-1)部分里继续寻找,这个时候把F(n-1)分割成F(n-2)+F(n-3),所以k要减1。
  • 如果中间值小于目标值,则要在F(n-2)部分里继续寻找,这个时候把F(n-2)分割成F(n-3) + F(n-4),所以k要减2。

代码实现

public class FbinacciSearch {
​
    static int maxsize = 20;
​
    public static void main(String[] args) {
        int[] arr = {1,8,10,89,1000,1234};
        System.out.println(search(arr,0,arr.length,1234));
    }
​
    public static int[] fbi(int maxsize){
        int[] res = new int[maxsize];
        res[0] = 1;
        res[1] = 1;
        for(int i = 2;i < maxsize;i++){
            res[i] = res[i-1] + res[i-2];
        }
        return res;
    }
    public static int search(int[] arr,int low,int high,int target){
        int[] fbi = fbi(maxsize);
        int mid = 0;
        int k = 0;
        while(high > fbi[k]){
            k++;
        }
        int[] temp = Arrays.copyOf(arr,fbi[k]);
        for(int i = high;i < temp.length;i++){
            temp[i] = temp[high-1];
        }
        while(low <= high){
            mid = low + fbi[k-1] - 1;
            if(temp[mid] == target){
                if(mid < high){
                    return mid;
                }
                return high;
            }
            else if(temp[mid] < target){
                low = mid + 1;
                k = k-2;
            }
            else if(temp[mid] > target){
                high = mid -1;
                k = k-1;
            }
        }
        return -1;
    }
}