算法 - 查找 - 斐波那契查找 (Fibonacci Search)

算法 - 查找 - 斐波那契查找 (Fibonacci Search)

返回分类:全部文章 >> 基础知识

返回上级:算法 - 查找与排序 (Searching and Sorting)

本文将用C++实现通用模板斐波那契查找算法,复制代码直接可使用。

在查看本文之前,需要一些程序语言的基础。

还需要熟悉 算法 - 查找 - 二分查找 (Binary Search)



1 斐波那契查找简述 (Introduction)

斐波那契查找,是二分查找的一个变种。其时间复杂度 O(log2n) 。

斐波那契数列,又称黄金分割数列, F = { 1 , 1 , 2 , 3 , 5 , 8 , 13 , 21 , 34 , . . . } F = \{ 1, 1, 2, 3, 5, 8, 13, 21, 34, ... \} F={ 1,1,2,3,5,8,13,21,34,...} 数学表达式:

F 0 = 1 F 1 = 1 F 2 = F 0 + F 1 ⋮ F i = F i − 2 + F i − 1 ( i ≥ 2 ) \begin{aligned} F_0 &= 1 \\ F_1 &= 1 \\ F_2 &= F_0 + F_1 \\ & \vdots \\ F_i &= F_{i-2} + F_{i-1} \quad (i \geq 2) \end{aligned} F0F1F2Fi=1=1=F0+F1=Fi2+Fi1(i2)

之所以它又称为黄金分割数列,是因为它的前一项与后一项的比值随着数字数量的增多逐渐逼近黄金分割比值0.618。

所以斐波那契查找改变了二分查找中原有的中值 mid 的求解方式,其 mid 不再代表中值,而是代表了黄金分割点:

m i d = l e f t + F b l o c k − 1 − 1 mid = left + F_{block - 1} - 1 mid=left+Fblock11

  • 二分查找,以一半元素来分割数组;

  • 斐波那契查找,以黄金分割点来分割数组。

假设表中有 n 个元素,查找过程为取区间中间元素的下标 mid ,对 mid 的关键字与给定值的关键字比较:

  • (1)如果与给定关键字相同,则查找成功,返回在表中的位置;

  • (2)如果给定关键字大,向右查找并减小2个斐波那契区间;

  • (3)如果给定关键字小,向左查找并减小1个斐波那契区间;

  • (4)重复过程,直到找到关键字(成功)或区间为空集(失败)。

通常情况下:

  • 返回值,代表下标;

  • 返回-1,代表没有找到关键字;

举例,假设有集合 e0=2, e1=3, e2=7, e3=14, e4=22, e5=33, e6=55, e7=75, e8=89, e9=123 。

查找元素44的过程:

  • 已知:

    • 元素数量size = 10
    • 下标区间 [low, high] 为left = 0right = 9
  • 初始化的斐波那契数列为 F i b = { 1 , 1 , 2 , 3 , 5 , 8 , 13 } Fib = \{ 1, 1, 2, 3, 5, 8, 13 \} Fib={ 1,1,2,3,5,8,13} ,即斐波那契数列最后一位要比size - 1大。

  • 此时查找第一步为:此时刚初始化完,斐波那契数列最后一个区间为第6个区间,即区间(8, 13);第8个数字为当前黄金分割点,则第8个数字下标为下标7,检测的数字为 e7 ;以8分割数组后,左区间为(1, 8)。

    b l o c k 0 = 6 m i d 0 = l e f t 0 + F i b [ b l o c k 0 − 1 ] − 1 = 0 + 8 − 1 = 7 i n d e x 0 = min ⁡ ( m i d 0 , s i z e − 1 ) = 7 ∵ ( e = 44 ) < ( E [ i n d e x 0 ] = 75 ) (小于,去左区间) ∴ l e f t 1 = l e f t 0 = 0 r i g h t 1 = m i d 0 − 1 = 6 b l o c k 1 = b l o c k 0 − 1 = 5 \begin{array}{rl} block_0 &= 6 \\ mid_0 &= le

  • 28
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
斐波那契查找算法是一种基于二分查找算法查找算法,它利用了斐波那契数列的特性来确定查找的位置。下面是斐波那契查找算法的设计步骤: 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 ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值