C实现 费氏查找算法

问题引入

        费氏数列即斐波那契数列。

        斐波那契数列,又称黄金分割数列,数列形式为: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);	// 对右边进行递回
	}
}

运行结果

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

等日出看彩虹

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值