斐波那契查找(Fibonacci Search)

1Fibonacci数列

“有小兔一对,若等二月它们成年,第三月生下一对小兔,以后每月生产一对小兔,而所生小兔亦在第二月成年,第三月生产另一对小兔,以后亦每月生产小兔一对。假定每生产一对小兔,必为一雌一雄,且均无死亡,试问一年后共有小兔几对?

分析:首先观察下头七个月的情况,为此引入下述记号,用 表示原来的一对小兔, =12……12)表示 月生的一对小兔子, 表示第 对小兔子两个月以后又生的第 对小兔子,依次类推如表。

月份

 

对数

1

1

2

1

3

2

4

3

5

    

5

6

    

8

7

       

13

从表中可知七月份共有兔子13对;还可看出,从三月份开始,每月的兔子总数恰好等于它前面两个月的兔子总数之。按这规律可写出数列1123581321345589144可见一年后共有兔子144对。我们这道题运用的是初等数学的归那法,通过对问题的分析列表并计算得出结论。

这是一个有限数列,按上述规律写出无限数列就叫做Fibonacci数列(这是为了纪念兔子繁殖问题的创始人意大利数学家裴波那契),其中的每一项叫做Fibonacci数。若令 此数列有下面的递推关系:

Fibonacci数列紧密相关的一个重要极限是 ,这恰好是黄金分割比。除了与黄金分割有联系外,Fibonacci数列还出现在为数众多的领域,如某些叶子的排列,某些花的花瓣数,另外蜜蜂的家谱、钢琴音阶的排列也有该数列的特点。

 

2Fibonacci二叉树的形成

1.以数据个数N来决定FibonacciK阶(k-order

j=0 Fib(0)=0

j=1 Fib(1)=1

j=2 Fib(2)=1

j=3 Fib(3)=2

j=4 Fib(4)=3

 

……

j=N  Fib(N)= Fib(N-1)+Fib(N-2)

设计最小的k值,使得Fib(k+1)>N+1

2K=0k=1则表示Fibonacci只有一个结点,其余别无它物。

3k>=2,则表示Fibonacci的根为Fib(k),左子树为(k-1)阶Fibonacci树(其根为Fib(k-1)右子树为k-2)阶Fibonacci树(其根为Fib(k)+Fib(k-2)),上面的算法适用于N+1值为Fibonacci树,若N+1不为Fibonacci树,则找出M使得Fib(k)<N+1,再依上述算法建立Fibonacci树,最后把Fibonacci树的各结点数据减去M,就可以了。

3Fibonacci差值原则

1)左子树为负,右子树为正。

2)如图所示:

步骤:

假设数据个数有nn比某一Fibonacci数小,满足下列的运算式,如下所示:

Fa>=n+1

Fa-1就是这棵Fibonacci树的树根,而Fa-3则是开始的差值。如果我们要查找一个值key。首先我们比较数组索引和key,而得到下列的三种情况,如下所示:

1.  key比较小,则我们查找1Fa-1-1的数据。

2.  key比较大,则我们查找Fa-1+1Fa-1的数据。

3.  key与数组索引Fa-1的值相等,表示查找成功。

4.  继续上述的步骤直到找到键值或Fibonacci树的差值为零。

 

C语言程序

fib[]={0,1,1,2,3,5,8,13,21,34,……}

int fib_search(int n,int key)
{ int index,mid fn1,fn2,temp;

for(index=0; fib[index]<n+1;index++);

mid=fib[index-1];

fn1=fib[index-2];

fn2=fib[index-3];

while(mid!=0){

  if(key<data[mid].key)

   if (fn2<=0)

     mid=0;

   else{

    mid=mid-fn2;

    temp=fn1;

    fn1=fn2;

    fn2=temp-fn2;}

}

else if(key>data[mid-1].key)

  if(fn1<=1)

    mid=0;

  else{

    mid=mid+fn2;

    fn1=fn1-fn2;

    fn2=fn2-fn1;}

else

   return  --mid;

  }

return -1;

}

 

例:利用斐波那契查找法查找某一数值数据

 

原始数据:34  16  27  9  75  42  82  95

排序后的数据:

    d[1]  d[2]  d[3]  d[4]  d[5]  d[6]  d[7]  d[8]

    9     16   27    34    42   75   82   95

利用算法规则,生成斐波那契树,如图所示:

比如要查找key=34,此时从树根开始比较:

(1)       key>树根时,往右子树根开始比较;

(2)       key<树根时,往左子树根开始比较;

(3)       key=树根时,表示数据找到。

过程如下:

(1)       key=34<82,往左子树查找->第一次;

(2)       key=34<42,往左子树查找->第二次;

(3)       key=34>27,往右子树查找->第三次;

(4)       key=34,数据找到->第四次。

共查找四次

效率:

斐波那契查找与折半查找的时间复杂度间同为Olog2(log2n),平均情况下,斐波那契查找优于折半查找,但最坏情况下则差于折半查找。斐波那契查找优点是只有加、减运算。折半查找有除法运算。缺点是每次必须计算下个级数。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值