斐波那契查找法

斐波那契查找法又称黄金分割查找法
本文参考网址:http://blog.fishc.com/2935.html
黄金比例又称黄金分割,是指事物各部分间一定的数学比例关系,即将整体一分为二,较大部分与较小部分之比等于整体与较大部分之比,其比值约为1:0.618或1.618:1。
0.618被公认为最具有审美意义的比例数字,这个数值的作用不仅仅体现在诸如绘画、雕塑、音乐、建筑等艺术领域,而且在管理、工程设计等方面也有着不可忽视的作用。因此被称为黄金分割。
大家记不记得斐波那契数列:1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89…….(从第三个数开始,后边每一个数都是前两个数的和)
然后我们会发现,随着斐波那契数列的递增,前后两个数的比值会越来越接近0.618,利用这个特性,我们就可以将黄金比例运用到查找技术中。

这里写图片描述

因为斐波那契数列遵循: fa[k]=f[k-1]+fa[k-2];
对于fa[k]-1个数,我们按上图所示进行分割,然后进行查找
fa[k]-1==f[k-1]-1+fa[k-2]-1+1;
其中mid = low +fa[k-1]-1;

优点:只需进行加减运算

/*Fibonacci 查找法*/

#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 40//数组长度
#define FA_NUM  10

void Fibonacci_Array(int *a,int n)
{
    int i;//计数
    a[0]=1;
    a[1]=1;
    for(i=2;i<n;i++)
    {
        a[i]=a[i-1]+a[i-2];
    }

}
int Fibonacci_Search(int * Tab,int n,int target)
{
    int left,right,mid,i,k;
    int fa[FA_NUM];
    Fibonacci_Array(fa,FA_NUM);//产生斐那波契数列

    k = 0;
    while(n>fa[k]-1)//检查表中元素个数
    {
        k++;
    }
    for(i=n+1;i<=fa[k]-1;i++)//把不够的元素用最后一个元素填上
    {
        Tab[i]=Tab[n];
    }

    left = 1;
    right = fa[k]-1;
    while(left<=right)
    {

        mid = left+fa[k-1]-1;
        printf("left:%d,right:%2d,k:%2d,%2d,%2d,%2d\n",left,right,k,fa[k]-1,fa[k-1]-1,mid);
        if (target <Tab[mid])
        {
            right = mid -1;
            k -=1;
        }
        else if(target >Tab[mid])//fa[k]=fa[k-1]+fa[k-2];
        {
            left = mid +1;
            k -=2;
        }
        else
        {
            if (mid<n)
            {
                return mid;
            }
            else
            { 
                return n;

            }
        }
    }
    return 0;

}
void main()
{
    int table[MAXSIZE]={0,1,3,15,23,26,28,30,35,37,39,50};//真正需要查的表,从下标1开始
    int target = 1;//目标值
    int fa[FA_NUM],location;
    /*测试代码,测试Fibonacci_Array()函数*/
    /*Fibonacci_Array(fa,FA_NUM);
    for (i=0;i<FA_NUM;i++)
    {
        printf("%d,%d\n",i,fa[i]);
    }*/
    location = 0;
    if(location = Fibonacci_Search(table,10,target))
    {
        printf("%d\n",location);
    }
    else
    {
        printf("not found\n");
    }

    getchar();

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值