码迷,mamicode.com
首页 > 编程语言 > 详细

查找算法1-Fibonacci查找

时间:2017-08-15 12:35:44      阅读:223      评论:0      收藏:0      [点我收藏+]

标签:play   参考   arch   tts   suv   而不是   kvo   ccs   logs   

斐波那契查找是一种在有序表中高效查找指定元素的算法,比折半查找要复杂一些,主要复杂在要多做不少准备工作。下面看它的工作流程:

        1.计算并保存一个斐波那契序列的数组,方便以后取值。数组名记为f,例如f[1]=1,f[2]=1,f[3]=2,f[4]=3,f[5]=5,f[6]=8,f[7]=13,f[8]=21

        2.把有序数组的长度扩充到a.length=f[k]-1,k是满足条件的最小值,比如数组长度为13,那么就把它长度扩充到f[8]-1=20,所有在末尾添加的扩充元素都是原数组最后一个元素的复制品

        3.找到mid元素,不断进行二分比较,直到找到目标元素为止,这一步的做法与折半查找一模一样,仅仅是计算mid的公式从(low+high)/2改为low+(f[k-1]-1)。

        斐波那契查找的理解难点就一个:为什么需要把数组长度扩充到f[k]-1而不是f[k]或者 f[k+1]?这是为了能正确递归计算mid值,看下图可发现 f[k]-1 = (f[k-1] + f[k-2]) - 1 = (f[k-1]-1) + 1 + (f[k-2]-1),中间的1就是我们二分的锚点mid,如果目标在左区,数组长度就缩到(f[k-1]-1),如果在右区,数组长度就缩到 (f[k-2]-1),否则就等于mid完成查找。而(f[k-1]-1)又能拆成(f[k-2]-1)+1+(f[k-3]-1),这样递归分割下去就 能不断的缩小区间直至找到目标。

 技术分享

 

 

#include <stdio.h>
#define LEN 9
#define MAXSIZE 100

int F[50];//fibonacci数列
//构造fibonacci数列
void FibonacciArray(int * a){
    int i;
    a[0]=1;
    a[1]=1;
    for(i=2; i<50; i++){
        a[i]=a[i-1]+a[i-2];
    }
}

//进行fibonacci查找,返回0即查找失败,否则返回找到的下标
int FibonacciSearch(int * a,int n,int key){
    int k=0,i;
    int mid,low=1,high=n;
    while(n>F[k]-1)
        k++;//确定初始k值
    
    for(i=n+1; i<=F[k]-1; i++ ){
        a[i]=a[n];    //补全a[n+1]到a[F[k]-1],使之都==a[n]
    }
    //开始查找
    while(low<=high){//注意
        mid=low+F[k-1]-1;
        if(a[mid]>key){//如果中间值比要查找的值大
            high=mid-1;
            k=k-1;
        }else if(a[mid]<key){
                low=mid+1;
                k=k-2;
            }else{//a[mid]==key
                if(mid<=n) return mid;
                    else if(mid>n)//说明找到的下标在原来填补的位置上,是和a[n]相同的,所以返回n
                        return n;
            }
                
    }
    return 0;//返回0,即key不在数组a中
}
int main(){

int a[LEN+1]={0,8,23,45,78,89,25,68,47,59};//设首位为哨兵
int arr[MAXSIZE]={0};//设一个足够大的数组,代入函数计算
for(int i=0; i<LEN+1; i++){
    arr[i]=a[i];
}

int result;
int key=59;
FibonacciArray(F);//返回[1,1,2,3,5,...]
//printf("%d",F[7]);
result=FibonacciSearch(arr,LEN,key);
if(result!=0){
    printf("%d存在数组a中,等于a[%d]\n",key,result);
}else
    printf("数组a中不存在%d\n",key);

return 0;
}

 结果:

技术分享

之前写的时候返了一个错误,while(low<=high)小于等于写成了<;

 

参考:

[1]大话数据结构,p.303-304

[2]http://blog.csdn.net/lzdidiv/article/details/59784694

查找算法1-Fibonacci查找

标签:play   参考   arch   tts   suv   而不是   kvo   ccs   logs   

原文地址:http://www.cnblogs.com/Allen-win/p/7364414.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!