查找--斐波那契查找

1、什么是斐波那契数列?

1、1、2、3、5、8、13、21、……

斐波那契数列又被成为黄金分割数列,因为  前一项/后一项越来越趋近于0.618

由上面的数列,可以发现 除了前两项,后面每一项都是前两项的和,如3+5=8、8+13=21.....

由此可以得到一下等式

F(n)=F(n-1)+F(n-2)    (除了前两项)

2、斐波那契查找和斐波那契数列有什么联系?

  斐波那契查找原理与前两种相似,仅仅改变了中间结点(mid)的位置,mid不再是中间或插值得到,而是位于黄金分割点附近,即mid=low+F(k-1)-1(F代表斐波那契数列)

  关于F(k)-1

由斐波那契数列可知,F(k)=F(k-1)+F(k-2),那F(k)-1=(F(k-1)-1)+(F(k-2)-1)+1,所以数组长度只要满足 F(k)-1,就可以将数组分为F(k-1)-1F(k-2)-1左右两部分,其中mid=low+F(k-1)-1

3、代码实现

目标;查找99
int[] a={0,16,24,35,47,59,62,73,88,99};
public static int MaxSize=20;  //先为斐波那契数列设置长度
    //构建你波拉契数列
    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;
    }
public static int fibSearch(int[] arr,int key){
        int left=0;  //初始指向最数组最左边
        int right=arr.length-1; //初始指向最数组最右边
        int k=0;  //指示斐波那契数列的下标,初始为0是为了根据数组长度确定数组需要扩展的长度
        int mid=0;
        int[] f=fib(); //获取斐波那契数列
        while (arr.length>f[k]-1){ //这里的f[k]是arr距离斐波那契数列最近的数值,为什么-1,为了符合数组特性(数组最大元素下标是数组长度-1)
            k++;
        }
        int[] temp=Arrays.copyOf(arr,f[k]); //为什么构建一个新数组,因为下面需要对数组进行扩展,查找最后还要用到原始数组,所以不能用原始数组
        //扩展数组
        for (int i=right+1;i<temp.length;i++){  //这里为什么用temp.length?因为上面Arrays.copyOf(arr,f[k])已经对数组扩展了,这里我们进行的是把扩展的值都改为原始数组的最大值
            temp[i]=arr[right];
        }

        while (left<=right){
            mid=left+f[k-1]-1;   //这里就是为mid确定位置,位置确定请看上面的图
            if (key<temp[mid]){  //如果当前mid值大于key,说明key在mid左边部分,继续对左边的F[k-1]-1部分进行分割
                right=mid-1;
                k--;
            }else if (key>temp[mid]){
                left=mid+1;
                k-=2;
            }else {
                if (mid<arr.length){ //查找值的下标在arr数组额范围内,直接返回
                    return mid;
                }else { //不在就返回right,为什么?因为后面几位的值和right的值是一样的,说明查找的值就是right
                    return right;
                }
            }
        }
        //都找不到返回-1
        return -1;

    }
public static void main(String[] args) {
        int[] a={0,16,24,35,47,59,62,73,88,99};
        int key=99;
        System.out.println(fibSearch(a,key));
    }

4、斐波那契查找缺陷

  • 只适用于顺序表
  • 有序数组

原文地址:https://www.cnblogs.com/han200113/p/11745808.html

时间: 2024-10-17 21:26:48

查找--斐波那契查找的相关文章

【算法】先生,您点的查找套餐到了(二分、插入和斐波那契查找)

参考资料 <算法(java)>                           — — Robert Sedgewick, Kevin Wayne <数据结构>                                  — — 严蔚敏 Interpolation Search[插值查找]     — —  维基百科 Fibonacci Search[斐波那契查找]   — —  GeeksforGeeks 根据输入的一个关键字(Key),  在一个有序数组内查找与该关键

二分查找和斐波那契查找

二分查找 说明:查找的数组或列表必须是有序的,若无序,先进行排序 复杂度:时间复杂度 O(log2n),空间复杂度O(n) C++源码(递归和非递归两个版本) #include <iostream> using namespace std; int a[] = { 1, 2, 3, 4, 5, 6, 8 }; int BinarySearch1(int l, int r, int value) { int mid = (l + r) / 2; if (l == r && a[l

斐波那契查找原理详解与实现

最近看见一个要求仅使用加法减法实现二分查找的题目,百度了一下,原来要用到一个叫做斐波那契查找的的算法.查百度,是这样说的: 斐波那契查找与折半查找很相似,他是根据斐波那契序列的特点对有序表进行分割的.他要求开始表中记录的个数为某个斐波那契数小1,即n=F(k)-1;  开始将k值与第F(k-1)位置的记录进行比较(及mid=low+F(k-1)-1),比较结果也分为三种  1)相等,mid位置的元素即为所求  2)>   ,low=mid+1,k-=2;说明:low=mid+1说明待查找的元素在

数据结构之---C语言实现斐波那契查找

斐波那契查找的核心思想是: 1)当key=a[mid]时,查找成功: 2)当key<a[mid]时,新的查找范围是第low个到第mid-1个,此时范围个数为F[k-1] - 1个,即数组左边的长度,所以要在[low, F[k - 1] - 1]范围内查找: 3)当key>a[mid]时,新的查找范围是第mid+1个到第high个,此时范围个数为F[k-2] - 1个,即数组右边的长度,所以要在[F[k - 2] - 1]范围内查找. 代码: //斐波那契查找 //杨鑫 #include <

斐波那契查找算法完整C代码

/* 斐波那契查找法 */ #include <stdio.h> #include <stdlib.h> int Fib( int k ) { if( 1 == k || 2 == k ) return 1; else return Fib(k-1)+Fib(k-2); } int FibSearch( int *a, int n, int key ) { int k = 1; int nFib; int *b; int low, mid, high; while( Fib(k)

"二分查找(Binary Search)"与"斐波那契查找(Fibonacci Search)"

首先,我们来看一个笔者的拙作,一段二分查找代码 //返回值是key的下标,如果A中不存在key则返回-1 template <class T> int BinSearch(T* A, const T &key, int lo, int hi) {     int mid;     while(lo<hi)     {         mid = lo + (hi-lo)/2;         if(key < A[mid])             hi = mid-1;

(java)有序表查找——折半查找,插值查找,斐波那契查找

有序表查找 /* 主函数 */ public class OrderTableSearch { public static void main(String[] args) { int [] a= {0,1,16,24,35,47,59,62,73,88,99}; System.out.println(FibonacciSearch(a, 10, 88)); System.out.println(InsertKeySearch(a, 10, 88)); System.out.println(Bi

斐波那契查找(超详解)

// 斐波那契查找.cpp #include <iostream> #include <string.h> using namespace std; const int max_size=20;//斐波那契数组的长度 /*构造一个斐波那契数组*/ void Fibonacci(int * F) { F[0]=0; F[1]=1; for(int i=2;i<max_size;++i) F[i]=F[i-1]+F[i-2]; } /*定义斐波那契查找法*/ int Fibona

斐波那契查找

斐波那契查找又称为黄金比例分割查找, 大家记不记得斐波那契数列:1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89…….(从第三个数开始,后边每一个数都是前两个数的和) 然后我们会发现,随着斐波那契数列的递增,前后两个数的比值会越来越接近0.618,利用这个特性,我们就可以将黄金比例运用到查找技术中. 黄金比例又称黄金分割,是指事物各部分间一定的数学比例关系,即将整体一分为二,较大部分与较小部分之比等于整体与较大部分之比,其比值约为1:0.618或1.618:1. 0.61