斐波那契查找

目录

斐波那契查找的基本介绍

斐波那契(黄金分割法)原理

斐波那契查找的代码实现


斐波那契查找的基本介绍

在中学阶段我们都学过黄金分割比为0.618,在斐波那契数列中,相邻两个数的比例,无限接近0.618

斐波那契(黄金分割法)原理

斐波那契查找与前两种查找方法相似,仅仅是改变了中间节点mid的位置,mid不再是由二分或者差值得到,而是位于黄金分割点附近。即:mid=left+F[k-1]-1,(F表示斐波那契数列),如下图所示:

对于F[k]-1的理解

(1)因为斐波那契数列满足:F[k]=F[k-1]+F[k-2],所以F[k]-1=(F[k-1]-1)+(F[k-2]-1)+1

该式说明:对于长度为F[k]-1的斐波那契数列,我们总能找到一个mid,将其分为长度为F[k-1]-1和F[k-2]-1两个部分。

(2)类似的,对于每一子段,也可以用相同的方法分割。

(3)但是顺序表的长度不一定为F[k]-1,所以我们要对原先的表进行扩容。这里只需要让F[k]-1>=n就可以。新增的位置都赋值为n位置的值

    int k = 0;//记录F的下标
	//找到满足条件的下标 F[k]-1>n
	while (n > F[k] - 1) {
		++k;
	}

	int* tmp = new int[F[k] - 1]; //将数组扩展到F[k]-1的长度
	memcpy(tmp, a, n * sizeof(int));
	//扩展数组,多出的部分按照最后一个元素处理
	for (int i = n; i < F[k] - 1; i++) {
		tmp[i] = a[n - 1];
	}

斐波那契查找的代码实现

(1)首先我们要得到一个斐波那契数列

#define max_size 20

void Fibonacci(int* F)
{
	F[0] = 1;
	F[1] = 1;
	for (int i = 2; i < max_size - 1; i++) {
		F[i] = F[i - 1] + F[i - 2];
	}
}

(2)先扩容,然后进行查找

int Fibonacci_Search(int* a, int n, int k) {
	int low = 0;
	int high = n - 1;

	int F[max_size];
	Fibonacci(F);

	int k = 0;//记录F的下标
	//找到满足条件的下标 F[k]-1>n
	while (n > F[k] - 1) {
		++k;
	}

	int* tmp = new int[F[k] - 1]; //将数组扩展到F[k]-1的长度
	memcpy(tmp, a, n * sizeof(int));
	//扩展数组,多出的部分按照最后一个元素处理
	for (int i = n; i < F[k] - 1; i++) {
		tmp[i] = a[n - 1];
	}

	while (left <= right) {
		int mid = low + F[k - 1] - 1;
		if (k < tmp[mid]) {
			high = mid - 1;
			k-=1;
		}
		else if (k > tmp[mid]) {
			low = mid + 1;
			k -= 2;
		}
		else
		{
			if (mid < n) {
				return mid;//说明mid即为查找到的位置
			}
			else{
				return n - 1;//mid>=n说明是在扩展的地方找到的,返回n-1(最后一位)
			}
		}
	}
	return -1;
}

这里需要理解的点

(1)对k的不同处理:

如果当k<a[mid]时,说明新范围是low到第mid-1个,此时范围个数为F[k-1]-1(即原先的左区间)

如果当k>a[mid]时,说明新范围是mid+1到第high个,此时范围个数为F[k-2]-1(即原先的右区间)

所以要对k进行k-=1(下一次在左区间细分)或者k-=2(下一次在右区间细分的处理) 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
斐波那契查找算法是一种基于二分查找算法查找算法,它利用了斐波那契数列的特性来确定查找的位置。下面是斐波那契查找算法的设计步骤: 1. 首先,需要确定斐波那契数列的长度,使得它大于等于待查找数组的长度。假设斐波那契数列的长度为n,那么有:F(n) = F(n-1) + F(n-2),其中F(0) = 0,F(1) = 1。 2. 然后,需要将待查找数组扩展到长度为n,扩展的部分用原数组的最后一个元素填充。 3. 接着,需要定义两个指针:low和high。初始时,low指向待查找数组的第一个元素,high指向斐波那契数列中第一个大于等于n的元素的下标减1。 4. 然后,需要计算mid的值,mid的值为low加上斐波那契数列中第k-1个元素的值,其中k为满足F(k)-1 >= n的最小值。 5. 然后,比较待查找数组中第mid个元素和要查找的元素的大小。如果待查找数组中第mid个元素小于要查找的元素,则将low指向mid+1;如果待查找数组中第mid个元素大于要查找的元素,则将high指向mid-1;否则,找到了要查找的元素,返回mid。 6. 重复步骤4和步骤5,直到low大于high为止。 下面是一个Python实现的斐波那契查找算法的例子: ```python def fibonacci_search(arr, x): n = len(arr) fib_k2 = 0 # F(k-2) fib_k1 = 1 # F(k-1) fib_k = fib_k1 + fib_k2 # F(k) while fib_k < n: fib_k2 = fib_k1 fib_k1 = fib_k fib_k = fib_k1 + fib_k2 offset = -1 while fib_k > 1: i = min(offset+fib_k2, n-1) if arr[i] < x: fib_k = fib_k1 fib_k1 = fib_k2 fib_k2 = fib_k - fib_k1 offset = i elif arr[i] > x: fib_k = fib_k2 fib_k1 = fib_k1 - fib_k2 fib_k2 = fib_k - fib_k1 else: return i if fib_k1 and arr[offset+1] == x: return offset+1 return -1 ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值