斐波那契查找

数组总长度为F[K]-1,mid前面长度为F[K-1]-1,后面长度为F[K-2]-1,mid在黄金分割点。
斐波那契查找_第1张图片

#include
using namespace std;

const int max_size = 20;					//斐波那契数组的长度  

void Fibonacci(int *F)						//构造一个斐波那契数组
{
	F[0] = 0;
	F[1] = 1;
	for (int i = 2; i < max_size; i++)
		F[i] = F[i-1] + F[i-2];
}
/*定义斐波那契查找法*/
int Fibonacci_search(int *a, int n, int key) //a为要查找的数组,n为数组长度,key为关键字 
{
	int low = 0;
	int high = n - 1;
	int mid;

	int F[max_size];
	Fibonacci(F);					//构造一个斐波那契数组F   

	int k = 0;
	while (n>F[k]-1)				//计算n位于斐波那契数列的位置  
		k++;

	int *tmp;					//将数组a扩展到F[k]-1的长度  
	tmp= new int[F[k] - 1];

	memcpy(tmp,a,n*sizeof(int));
	/*函数原型:void *memcpy(void *dest, const void *src, size_t n);
      功能:从源src所指的内存地址的起始位置开始拷贝n个字节
	  到目标dest所指的内存地址的起始位置中*/
	for (int i = n; i < F[k] - 1; i++)
		tmp[i] = a[n - 1];

	while (low<=high)
	{
		mid = low + F[k - 1] - 1;
		if (tmp[mid]>key)
		{
			high = mid - 1;
			k = k - 1;
		}
		else if (tmp[mid] < key)
		{
			low = mid + 1;
			k = k - 2;
		}
		else
		{
			if (mid >= n)
				return n - 1;
			else
				return mid;
		}
	}
	delete []tmp;					//释放new出来的内存
	return -1;
}

int main()
{
	int a[] = { 5, 16, 39, 45, 51, 98, 100, 202, 226, 321, 368, 444, 501 };
	cout << Fibonacci_search(a, sizeof(a)/sizeof(a[0]), 100);
	return 0;
}

时间复杂度:O(log n)
斐波那契查找的理念:让mid保持在数组的黄金分割点处,mid前面长度为F[K-1]-1,后面长度为F[K-2]-1,数组总长度为F[K]-1,mid在黄金分割点。

与二分查找比较:

  • 斐波那契查找的平均性能比折半查找好;
  • 但最坏情况下性能却比折半查找差;
  • 它还有一个优点就是分割时只需进行加减运算。

与二分查找相比,斐波那契查找算法的明显优点在于它只涉及加法和减法运算,而不用除法。因此,斐波那契查找的平均性能要比折半查找好。

你可能感兴趣的:(数据结构,数据结构心法指南)