什么是斐波那契查找

斐波那契数列,又称黄金分割数列,指的是这样一个数列:1、1、2、3、5、8、13、21、····,在数学上,斐波那契被递归方法如下定义:F(1)=1,F(2)=1,F(n)=f(n-1)+F(n-2) (n>=2)。该数列越往后相邻的两个数的比值越趋向于黄金比例值(0.618)。

斐波那契查找就是在二分查找的基础上根据斐波那契数列进行分割的。在斐波那契数列找一个等于略大于查找表中元素个数的数F[n],将原查找表扩展为长度为F[n](如果要补充元素,则补充重复最后一个元素,直到满足F[n]个元素),完成后进行斐波那契分割,即F[n]个元素分割为前半部分F[n-1]个元素,后半部分F[n-2]个元素,找出要查找的元素在那一部分并递归,直到找到。

斐波那契查找的时间复杂度还是O(log 2 n ),但是 与折半查找相比,斐波那契查找的优点是它只涉及加法和减法运算,而不用除法,而除法比加减法要占用更多的时间,因此,斐波那契查找的运行时间理论上比折半查找小,但是还是得视具体情况而定。

对于斐波那契数列:1、1、2、3、5、8、13、21、34、55、89……(也可以从0开始),前后两个数字的比值随着数列的增加,越来越接近黄金比值0.618。比如这里的89,把它想象成整个有序表的元素个数,而89是由前面的两个斐波那契数34和55相加之后的和,也就是说把元素个数为89的有序表分成由前55个数据元素组成的前半段和由后34个数据元素组成的后半段,那么前半段元素个数和整个有序表长度的比值就接近黄金比值0.618,假如要查找的元素在前半段,那么继续按照斐波那契数列来看,55 = 34 + 21,所以继续把前半段分成前34个数据元素的前半段和后21个元素的后半段,继续查找,如此反复,直到查找成功或失败,这样就把斐波那契数列应用到查找算法中了。

从图中可以看出,当有序表的元素个数不是斐波那契数列中的某个数字时,需要把有序表的元素个数长度补齐,让它成为斐波那契数列中的一个数值,当然把原有序表截断肯定是不可能的,不然还怎么查找。然后图中标识每次取斐波那契数列中的某个值时(F[k]),都会进行-1操作,这是因为有序表数组位序从0开始的,纯粹是为了迎合位序从0开始。所以用迭代实现斐波那契查找算法如下:

#include <stdio.h>  
  
#define FIB_MAXSIZE 100  
  
/** 
 * 生成斐波那契数列 
 * @param fib:指向存储斐波那契数列的数组的指针 
 * @param size:斐波那契数列长度 
 */  
void ProduceFib(int *fib, int size)  
{  
    int i;  
  
    fib[0] = 1;  
    fib[1] = 1;  
  
    for (i = 2; i < size; i++)  
    {  
        fib[i] = fib[i - 1] + fib[i - 2];  
    }  
}  
  
/** 
 * 斐波那契查找,查找成功返回位序,否则返回-1 
 * @param data:有序表数组 
 * @param length:有序表元素个数 
 * @param searchValue:待查找关键字 
 */  
int FibonacciSearch(int *data, int length, int searchValue)  
{  
    int low, high, mid, k, i, fib[FIB_MAXSIZE];  
  
    low = 0;  
    high = length - 1;  
  
    ProduceFib(fib, FIB_MAXSIZE);  
  
    k = 0;  
    // 找到有序表元素个数在斐波那契数列中最接近的最大数列值  
    while (high > fib[k] - 1)  
    {  
        k++;  
    }  
  
    // 补齐有序表  
    for (i = length; i <= fib[k] - 1; i++)  
    {  
        data[i] = data[high];  
    }  
  
    while (low <= high)  
    {  
        mid = low + fib[k - 1] - 1;   // 根据斐波那契数列进行黄金分割  
  
        if (data[mid] == searchValue)  
        {  
            if (mid <= length - 1)  
            {  
                return mid;  
            }  
            else  
            {  
                // 说明查找得到的数据元素是补全值  
                return length - 1;  
            }  
        }  
  
        if (data[mid] > searchValue)  
        {  
            high = mid - 1;  
            k = k - 1;  
        }  
  
        if (data[mid] < searchValue)  
        {  
            low = mid + 1;  
            k = k - 2;  
        }  
    }  
  
    return -1;  
}  
  
int main()  
{  
    int data[] = {1,3,5,7,9,11,13,15,17,19,21};  
  
    int index = FibonacciSearch(data, 11, 19);  
    printf("%d\n", index);  
  
    return 0;  
}

斐波那契查找的时间复杂度还是O(log2n),但是与折半查找相比,斐波那契查找的优点是它只涉及加法和减法运算,而不用除法,而除法比加减法要占用更多的时间,因此,斐波那契查找的运行时间理论上比折半查找小,但是还是得视具体情况而定

转载博客:https://www.cnblogs.com/lpfuture/p/7112450.html

斐波那契查找算法(黄金分割查找算法)相关推荐

  1. 数学之美|斐波那契数列与黄金分割

    14天阅读挑战赛 系列文章目录 趣味算法(第二版)读书笔记: day1: 序章|学习的方法和目标. day2:算法之美|打开算法之门与算法复杂性 day3.算法之美|指数型函数对算法的影响实际应用 d ...

  2. 算法:斐波那契(黄金分割法)查找算法

    斐波那契数列 斐波那契数列,该数列公式为F(K) = F(k-1) + F(k-2),即 1.1.2.3.5.8.13.21--.F(k-1)/f(K)随着K的递增,该数越来越接近黄金分割比例,所以该 ...

  3. php算法求出兔子数列,PHP算法:斐波那契数列的N种算法

    前言 前段时间,遇到优化计算斐波那契数列的常规递归方法,但是一时间并没有及时想到很好的方法,所以后面查找了相关资料,总结了多种计算解法,所以分享出来,和大家一起交流学习. 斐波那契数是什么 斐波那契数 ...

  4. “斐波那契数列”的两种算法

    "斐波那契数列"的两种算法 斐波那契数列有个规律:从第三个数开始,每个数是前两个数之和,比如: 1 1 2 3 5 8 13 21 34 55...... 现在通过两种方式(递归与 ...

  5. LeetCode 842. 将数组拆分成斐波那契序列(暴力查找)

    1. 题目 给定一个数字字符串 S,比如 S = "123456579",我们可以将它分成斐波那契式的序列 [123, 456, 579]. 形式上,斐波那契式序列是一个非负整数列 ...

  6. java求第k个斐波那契数_Java程序查找第n个斐波那契数

    可以通过多种方式找到第n个斐波那契数.在这里,我们将使用动态编程技术以及优化空间. 让我们看一个例子- 示例public class Demo{ static int fibo(int num){ i ...

  7. 斐波那契数列与黄金分割比以及矩阵形式推导

    数学上,斐波那契数列以递归的形式进行定义:  F 0 =0F 1 =1F n =F n−1 +F n−2    \begin{split} &F_0=0\\ &F_1=1\\ & ...

  8. 漫谈斐波那契数列与黄金分割比

    (一)奇妙的斐波那契数列: 斐波那契数列的由来是"兔子问题". 从中总结的规律就是: (1)每个月小兔子数 = 上个月的大兔子数: (2)每个月的大兔子数 = 上个月的大兔子数 + ...

  9. JavaScript递归函数实现斐波那契数列、黄金分割数列,递归定义与用法实例分析,

    递归 所递归函数就是在函数体内调用本函数.使用递归函数一定要注意,处理不当就会进入死循环.要避免进入死循环,写递归函数先要写一个结束条件(为了结束循环)递归函数一般比如阶乘问题. 下面的代码就是一个死 ...

  10. 数学的玄学-斐波那契数列与黄金分割

    斐波那契数列 斐波那契数列(Fibonacci sequence),又称黄金分割数列,因数学家莱昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为" ...

最新文章

  1. 数据库期末复习重点,临时抱佛脚高分通过考试
  2. c# ifram 刷新父页面
  3. Eclipse开发struts完全指南
  4. C++下简单的socket编程
  5. 查看eclipse安装了哪些插件
  6. 计算机网络之应用层:2、DNS域名解析系统
  7. [转载]Qt之获取本机网络信息
  8. Tomcat5的数据库连接池配置
  9. 【11月29】PF 粒子滤波的多维运动模型代码
  10. python nltk.download报错_python 文本转语音机器学习之nltk download安装测试包
  11. JavaScript零基础入门 1:JavaScript表格简介
  12. 出入库管理软件如何修改格式
  13. Pr入门系列之六:使用标记
  14. android app整包更新,uniapp热更新和整包更新
  15. 几代数字无线通信系统标准汇总
  16. 面试问接口如何测试?
  17. 广州大学计算机学院网安学硕复试经历
  18. haproxy MMM WordPress
  19. 收藏 | 100+篇大数据学习资讯,带你玩转大数据分析!
  20. 已注册的 FOURCC 代码和 WAVE 格式

热门文章

  1. Wilcoxon Signed-Rank Test
  2. C++读xml 文件信息
  3. Atitit SpringCache缓存使用 艾提拉 attilax总结 1. Spring的抽象已经做得够好了,适合于大多数场景,非常复杂的就需要自己AOP实现了。 1 1.1. 设置配置文件支持
  4. Atitit 签名规范 attilax总结 安全签名规范 v2 r99.docx
  5. Atitit 索引技术--位图索引
  6. Atitit 在线支付系统功能设计原理与解决方案 与目录
  7. atitit.RESTful服务的概览and框架选型
  8. paip.js input onclick失灵不起作用无反应的解决.txt
  9. paip.web service技术在 JAVA与.NET中的应用流程方案
  10. paip.提升用户体验---网站导航栏的设计