问题引入
费氏数列即斐波那契数列。
斐波那契数列,又称黄金分割数列,数列形式为:0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368……在数学上,斐波纳契数列根据以下递归方法定义:F(0)=0,F(1)=1,F(n)=F(n-1)+F(n-2)(n≥2,n∈N*)。数列的特点为:(1)从第3项开始,每一项都等于前两项之和。(2)第0项是0,第1项是第一个1。
费氏查找即利用费氏数列(斐波那契数列)作为间隔查找元素(确定下一元素的位置),通过划分区间加快区间收敛的速度,提高查找效率,时间复杂度为O(logn)。
代码实现
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX 15
#define SWAP(x,y) {int t; t = x; x = y; y = t;} //元素交换
void createfib(void);
int findx(int, int);
int fibsearch(int[], int);
void quicksort(int[], int, int);
int Fib[MAX] = {-999};
int main() {
int number[MAX] = {0};
int i, find;
srand(time(NULL));
for(i = 1; i <= MAX; i++){
number[i] = rand() % 100;
}
quicksort(number, 1, MAX);
printf("查找对象数列为:");
for(i = 1; i <= MAX; i++) printf("%d ", number[i]);
printf("\n\n输入寻找对象:");
scanf("%d", &find);
if((i = fibsearch(number, find)) >= 0) printf("\n数字 %d 在第 %d 个位置。",find,i);
else printf("\n找不到指定数");
printf("\n");
return 0;
}
// 建立费氏数列
void createfib() {
int i;
Fib[0] = 0;
Fib[1] = 1;
for(i = 2; i < MAX; i++) Fib[i] = Fib[i-1] + Fib[i-2];
}
//找x值
int findx(int n, int find){
int i = 0;
while(Fib[i] <= n) i++;
i--;
return i;
}
//查找
int fibsearch(int number[], int find){
int i, x, m;
createfib();
x = findx(MAX+1,find);
m = MAX - Fib[x];
x--;
i = x;
if(number[i] < find) i += m;
while(Fib[x] > 0){
if(number[i] < find) i += Fib[--x];
else if(number[i] > find) i -= Fib[--x];
else return i;
}
return -1;
}
void quicksort(int number[], int left, int right) { int i, j, k, s;
if(left < right) {
s = number[(left+right)/2]; i = left - 1;
j = right + 1;
while(1) {
while(number[++i] < s) ; // 向右找
while(number[--j] > s) ; // 向左找
if(i >= j) break;
SWAP(number[i], number[j]);//交换元素
}
quicksort(number, left, i-1); // 对左边进行递回
quicksort(number, j+1, right); // 对右边进行递回
}
}
运行结果