数组总长度为F[K]-1,mid前面长度为F[K-1]-1,后面长度为F[K-2]-1,mid在黄金分割点。
#include<iostream>
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在黄金分割点。
与二分查找比较:
- 斐波那契查找的平均性能比折半查找好;
- 但最坏情况下性能却比折半查找差;
- 它还有一个优点就是分割时只需进行加减运算。
与二分查找相比,斐波那契查找算法的明显优点在于它只涉及加法和减法运算,而不用除法。因此,斐波那契查找的平均性能要比折半查找好。