斐波那契查找算法分析

原创作品,出自 “晓风残月xj” 博客,欢迎转载,转载时请务必注明出处(http://blog.csdn.net/xiaofengcanyuexj)。

由于各种原因,可能存在诸多不足,欢迎斧正!

    刚接触程序设计的人可能会看的斐波那契数列。其递推通项公式为

              fib[i]=1                              i=0,1

              fib[i]=fib[i-1]+fib[i-2];       i>2

        这样一个可以根据数学推到进一步求得与i相关的通项公式

            《斐波那契查找算法分析》

         我们知道0.618是个魔力数,即通常所说的黄金分割点。黄金比例又称黄金分割,是指事物各部分间一定的数学比例关系,即将整体一分为二,较大部分与较小部分之比等于整体与较大部分之比,其比值约为1:0.618或1.618:1。

      《斐波那契查找算法分析》

     1.设data[i]为有序数列,i=0,1…n-1;计算斐波那契数列前m项,m是保证fib[m]>=n的最小数。

     2.low=0,high=n-1;

     3.mid=low+fib[m-1]-1

         如果data[mid]>key,则说明可能在左半部分,m=m-1;

         如果data[mid]<key,则说明可能在右半部分,m=m-2;

         则否找到key,正确定位即可。


    该算法的时间复杂度为O(n*Log(n)),和二分查找一样,但可以避开除法运算,在计算机中除法运算的占用资源比加减高得多。当然在很多时候可以用位运算避开除2运算。


#include<iostream>
using namespace std;

const int MAXN=20;
int fib[MAXN];

//预处理求出Fibonacci数列
void GetFibonacci()
{
	fib[0]=1,fib[1]=1;
	for(int i=2;i<MAXN;i++)
		fib[i]=fib[i-2]+fib[i-1];
}

//斐波那契数列查找
int FibonacciSearch(int key,int data[],int n,int &count)
{
	int m=0;
	while(n>fib[m]-1)
		m++;

	for(int i=n;i<=fib[m]-1;i++)
		data[i]=data[n-1];

	int low=0,high=n-1,mid;
	while(low<=high)
	{
		count++;
		mid=low+fib[m-1]-1;
		if(data[mid]>key)
		{
			high=mid-1;
			m=m-1;
		}
		else if(data[mid]<key)
		{
			low=mid+1;
			m=m-2;
		}
		else //找到这样的key
		{
			if(mid<n)
				return mid;
			return n-1;//原数组组后一个数
		}
	}
	return -1;
} 

//二分查找
int BinarySearch(int key,int data[],int n,int &count)
{
	int low=0,high=n-1,mid;
	while(low<=high)
	{
		count++;
		mid=(low+high)/2;
		if(data[mid]>key)
		{
			high=mid-1;
		}
		else if(data[mid]<key)
		{
			low=mid+1;
		}
		else return mid;
	}
	return -1;
}

int main()
{
	int data[100]={1,3,5,7,9,12,23,54,65,78,80,100};
	GetFibonacci();
	
	double Ave=0;
	int count;
	printf("以下是斐波那契数列查找的结果:\n");
	for(int i=0;i<12;i++)
	{
		count=0;
		int ans=FibonacciSearch(data[i],data,12,count);
		Ave+=ans;
		printf("%d出现在第%d位置,查找了%d次\n",data[i],ans,count);
	}
	printf("斐波那契数列平均查找参数为%0.2lf\n",Ave/12);

	Ave=0;
	printf("以下是二分查找的结果:\n");
	for(i=0;i<12;i++)
	{
		int ans=BinarySearch(data[i],data,12,count);
		Ave+=ans;
		printf("%d出现在第%d位置,查找了%d次\n",data[i],ans,count);
	}
	printf("二分查找平均查找参数为%0.2lf\n",Ave/12);

	return 0;
}

以下是运行结果截图

《斐波那契查找算法分析》

        以上部分内容取自先取博客,在此表示感谢!

    原文作者:查找算法
    原文地址: https://blog.csdn.net/xiaofengcanyuexj/article/details/17471413
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞