06 Find Fibonacci algorithm of cutting the number of columns that look

Fibonacci (Golden Section) search algorithm - based on an ordered array

Thinking

Fibonacci number {1,1,2,3,5,8,13,21} Fibonacci ratio found two adjacent forests of Number of infinitely close to the ratio of two adjacent numbers, infinitely close to the golden value 0.618

Fibonacci cut (golden) Principle: Fibonacci find: concubinage With the number of columns to find meager split point

Find Fibonacci principle similar to the first two, only to change the intermediate node (mid) position

It is no longer an intermediate or mid interpolated, but is located in the golden section

I.e., mid = low + F (k-1) -1 (F cut behalf Fibonacci series)

[Image dump the chain fails, the source station may have security chain mechanism, it is recommended to save the picture down uploaded directly (img-R4xqWST3-1578222737865) (images / 03.png)]

For understanding F (k-1) -1 of the

1) that the number of conveyance by a Fibonacci columns F [k] = F [k-1] + F [k-2] properties can be obtained (F [k] -1) = (F [k-1] -1) + (F [k-2] -1) +1

Description of formula: as long as the length of sequence table F. [K] -1 , it can be divided into the length of the table F [k-1] -1 and F [k-2] -1 two stages, i.e., as shown in FIG. . So that the intermediate position mid = low + F (k- 1) -1

2) Similarly, each sub-segment may be divided in the same manner

3Table sequence length n is not necessarily exactly equal to F [k] -1, it is necessary to increase the length of the original sequence table n to F [k] -1In so long as the value of k F [k] -1 of greater than or exactly equal to n, obtained by the following code, increasing the length of the sequence table, the new position (from n + 1 to F [k] -1 position) , n-Ode position value.

while(n>fib(k)-1){
    k++;
}

Code

package G查找;

import java.util.Arrays;

/**
 * @Author Zhou  jian
 * @Date 2020 ${month}  2020/1/5 0005  18:25
 * 斐波那契查找:借助菲薄纳妾数列找到分割点
 */
public class FibonacciSearch {

    static int maxSize = 20;

    public static void main(String[] args) {
        int[]  arr = {1,8,10,89,1000,1234};

        System.out.println(fibSearch(arr,11));
    }


    //因为后面我们mid=low+F(k-1)-1,需要使用到斐波那契数列,因此我们需要先获取到一个菲薄那切数列
    //非递归方式
    public static int[] fib(){
        int[] f = new int[maxSize];

        f[0]=1;
        f[1]=1;
        for(int i=2;i<maxSize;i++){
            f[i] = f[i-1]+f[i-2];
        }
        return f;
    }


    //编写菲薄纳妾查找算法
    //使用非递归的方式编写算法
    /**
     *
     * @param a  数组
     * @param key 我们需要查找的关键码(值)
     * @return
     */
    public static int fibSearch(int[] a,int key){

        int low = 0 ;
        int high = a.length-1;
        int k = 0; //表示菲波那切数值的下标  mid=low+F(k-1)-1  为这个表达式中的k
        int mid = 0; //存放mid至

        int[]  f = fib();//获取斐波那契数列

        //获取到斐波那契分隔数值的下标 k,才能容纳下待比较的数组
        while(high>f[k]-1){
            k++;
        }

        //因为f[k]值可能大于数组的长度,因此我们需要使用Arrays类构件一个新的数组,并指向a
        //不足的部分会使用0填充
        int[] temp = Arrays.copyOf(a,f[k]);

        //实际上需要使用a数组的最后的数填充temp
        //举例:
        //temp 1 8 10 89 1000 1234 0 0 0 =》 1 8 10 89 1000 1234 1234 1234 1234
        for(int i=high+1;i<temp.length;i++){
            temp[i]=a[high];
        }

        //使用while循环来处理,找到我们的数key
        while(low<=high){//只要这个条件
            mid = low + f[k-1]-1;
            if(key<temp[mid]){//说明我们应该继续向数组的前部分查找左边
                high = mid-1;
                //为什么k--?
                //1、全部的元素 =  前面的元素+后面的元素
                //2、f[k] = f[k-1]+f[k-2]
                //因为前面有f[k-1]个元素,所以继续拆分 f[l-1]=f[k-2]+f[k-3]
                //记载f[k-1]的前面继续查找 k--
                //即下次循环 mid=f[k-1-1]-1
                k--;
            }else if(key>temp[mid]){//说明我们应该继续向数组的后面(右面查找)
                low = mid+1;
                //为什么是k-2
                //1、全部元素=前面元素+后面元素
                //2、f[k]=f[k-1]+f[k-2]
                //因为后面有f[k-2]个元素所以我们可以继续拆分f[k-2]=f[k-3]+f[k-4]
                //即在f[k-2]的前面进行查找k -=2
                //即下次循环 mid=f[k-1-2]-1
                k -=2;
            }else{//找到
                //需要确定,返回的是哪个下标,为什么返回晓得????????
                if(mid<=high){
                    return mid;
                }else{
                    return high;
                }

            }
        }
        //没有找到
        return -1;

    }
    

}

Published 101 original articles · won praise 17 · views 10000 +

Guess you like

Origin blog.csdn.net/ZHOUJIAN_TANK/article/details/103846171