斐波那契查找法又称黄金分割查找法
本文参考网址: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();
}