作者前言

大家好,我是阿濠,今篇内容跟大家分享的是查找算法之斐波那契(黄金分割法)查找,很高兴分享到segmentfault与大家一起学习交流,初次见面请大家多多关照,一起学习进步.

一、斐波那契数列介绍

被我们称为"斐波拉契"的人,真实姓名叫列昂纳多来自比萨,这个数列出自他的书《算盘宝典》("Liber Abaci"),这本书奠定西方世界的数学基础,其中的算法方法一直沿用至今

什么是斐波那契数列?

斐波那契数列指的是这样一个数列: 0, 1, 1, 2, 3, 5, 8, 13, 21....

特别指出:第0项是0,第1项是第一个1

这个数列从第三项开始,每一项都等于前两项之和

斐波那契公式:F(k)=F(k-1)+F(k-2) 提示:F(1)=1 F(2)=1

初识美丽漂亮的黄金分割

黄金分割点是把一条线段分割为两部分,其中一部分与全长之比等于另一部分与这部分之比

由于按此比例设计的造型十分美丽,因此称为黄金分割,也称为中外比。

取其前三位数字的近似值是0.618,这是一个神奇的数字,会带来意向不大的效果

如果用大的斐波那契数 / 小的斐波那契数,也会发现越来越接近0.618

二、斐波那契(黄金分割法)查找算法介绍

基本原理

斐波那契查找原理与前两种相似,仅仅改变中间结点(mid)的位置mid不再是中间或插值得到,而是位于黄金分割点附近,即mid=low+F(k-1)-1 (F代表斐波那契数列)

对F(k-1)-1的理解:

1.根据公式: F[k] = F[k-1] + F[k-2],得到(F[k]-1) = (F[k-1]-1) + (F[k-2]-1) +1

2.因为有时候顺序表长度 n 不一定刚好等于 F[k]-1 ,将原数组查找表扩展为长度为F[k]-1 (如果要补充元素,则补充重复最后一个元素直到满足F[k]-1个元素),完成后进行斐波那契分割

3.如图所示,只要顺序表的长度为 F[k]-1 就可以分割为前半部分F[k-1]-1]个元素,后半部分 F[k-2]-1 个元素,从而确定中间位置mid = low+F(k-1)-1,找出要查找的元素在那一部分并递归,直到找到。

为什么(F[k]-1) = (F[k-1]-1) + (F[k-2]-1) +1 ?

因为根据公式得出:F[k] = F[k-1] + F[k-2],而斐波那契数列是指:{1,1,2,3,5,8, 13...}
若此时 k = 4 ,则代入公式:F[4] = F[4-1] + F[4-2]求出数列F[4] 结果:5
若此时代入(F[k]-1),那么本来 求F[4] 就变成求 (F[4]-1) 结果就是f[4] - 1 = 5 - 1 = 4
公式代入则是:(F[4]-1) = (F[4-1]-1) + (F[4-2]-1) 也就是(F[4]-1) = (F[3]-1) + (F[2]-1)
摊开来将F[4]=5、F[3]=3、F[2]=1 代入:(5-1) = (3-1) + (2-1) 此时再 + 1 就相等了

三、通过应用示例认识斐波那契查找算法

有序数组arr={1,8,10,89,1000,1234},进行斐波那契查找输入一数看看该数组是否存在此数,存在则求出下标,如果没有就返回-1 表示没有这个数

//因为后面我们mid=low+F(k-1)-1,需要使用到斐波那契数列
//因此我们需要先获取到一个斐波那契数列
//非递归方法得到一个斐波那契数列
public static int[] fib() {int[] f = new int[maxSize];f[0] = 1;f[1] = 1;for(int i=2;i<maxSize;i++){f[i] = f[i- 1] + f[i- 2];}return f;
}//使用非递归实现
/*** @param arr 数组* @param key 我们要查找的关键值(码)* @return 返回对应的下标 如果没有返回-1*/
public static  int fibSearch(int [] arr,int key) {int low = 0;int hight = arr.length - 1;int k = 0;//表示斐波那契分割数值下标int mid = 0;int f[] = fib();//获取斐波那契数列//判断顺序表长度 n 是否等于 F [k]-1 `,不等于将`原数组查找表扩展为长度为F[k]-1//假设当前传入的数组:1, 8, 10, 89, 1000, 1234  hight = 5//斐波那契数列:1,1,2,3,5,8,13...while (hight > f[k] - 1) {k++;}//如果要补充元素,则补充重复最后一个元素,直到满足F[k]-1个元素int[] temp = Arrays.copyOf(arr, f[k]);//此时 k =5  f[5]=8//因为arr[hight]代表最后一个元素,新数组temp = Arrays.copyOf(arr,f[k]);//所以若想最后元素当作填充元素就应该是从hight + 1 开始for (int i = hight + 1; i < temp.length; i++) {temp[i] = arr[hight];}while (low <= hight) {//按图所示进行黄金分割前部分+后部分mid = low + f[k - 1] - 1;//如果需要找的值key 小于temp[mid]说明我们应该继续向数组的前面查找(左边)if (key < temp[mid]) {hight = mid - 1;//往前缩范围//为什么是k--//1.全部元素= 前面的元素 + 后边元素//2. f[k] = f[k-1] + f[k-2]//之前(F[k]-1) = (F[k-1]-1) + (F[k-2]-1) +1//按图所示,目前我们这里是mid= low + f[k - 1] -1;//如果继续向数组的前面查找(左边)则应该是(F[k-1]-1)进行拆分//(F[k-1]-1)=(F[k-1-1]-1) + (F[k-2-2]-1) +1 = 4 = 2 + 1 + 1//即在f[k-1]-1 的前面继续查找k--//即下次循环mid = f[k-1-1] -1k--;}//我们应该继续向数组的后面查找(右边)if (key > temp[mid]) {low = mid + 1;//为什么是k -=2//1. f[k] = f[k-1] + f[k-2] .//2.因为后面我们有f[k-2],所以可以继续拆分 f[k-1] = f[k-3] + f[k-4]//3.即在f[k-2]的前面进行查找k -=2,即下次循环mid = f[k -1 - 2] -1k -= 2;}if (key == temp[mid]) {//因为之前如果要补充元素,则补充重复最后一个元素,直到满足F[k]-1个元素//如果小于hight代表是arr数组里的值if (mid <= hight) {return mid;} else {//否则说明查找得到的数据元素是temp数组里的补充值return hight;}}}return -1;
}

如果存在则求出下标,如果没有就返回-1表示没有这个数

执行代码测试一下数据看看,点击这里运行代码

四、算法复杂度分析

斐波那契查找的时间复杂度是:O(log 2 n )

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

五、斐波那契数列的有趣知识

计算中的斐波那契数列

让我们计算一下,头几个斐波那契数列的平方

毫无意外的,当你加上两个连续斐波那契的数字时,你会得到下一个斐波那契数,但是也许你不知道把斐波那契数的平方加起来会有什么有意思的结果?

没错,规律还在~事实上,还有一个规律,你计算一下头几个斐波那契数列的平方和

可能觉得它们不是斐波那契数,但是如果你看的够仔细,会发现背后隐藏着斐波那契数

那么你就会发现1 、1 、2 、3 、5 、8的各平方加起来 = 104 = 8x13 why?

用一个简单的图形解答一下,先让我们画一个1 乘 1 的方块

现在问大家一个问题:这个矩形的面积是多少?

一方面它的面积是:组成它的小矩形之和

一方面因为是矩形,它的面积:长 * 高

所以这就是为什么1 、1 、2 、3 、5 、8的各平方加起来 = 104 = 8x13

黄金矩形与黄金螺旋

通过上面的知识点了解了黄金分割线,那么我们来再了解一下黄金矩形与黄金螺旋

生活中的斐波那契

斐波那契数列在自然界中神奇的出现,一朵花的花瓣数量、向日葵的螺旋,菠萝上表面的凸起,一般都对应着某个斐波那契数列

简单的说,植物的生长点每个一个角度就会发展出一个侧芽,如果这个侧芽角度太过平庸,新芽旋转几周后之后就会与老的侧芽对在一起,即浪费空间又争夺资源


http://www.taodudu.cc/news/show-6035095.html

相关文章:

  • 解决真机识别为虚拟机,Sorry, this application cannot be run under a Virtual Machine
  • windows用虚拟机vmWare安装黑苹果及注意事项
  • Burpsuite配置抓apk流量代理设置脚本
  • 填坑记录——扫雷游戏的重置
  • 超详细分解c 语言——实现扫雷游戏(详解)
  • java的round函数怎么用_Java Math round()用法及代码示例
  • 布局5G旗舰移动市场 MediaTek发布天玑新品
  • 获取Android设备唯一标识(唯一序列号)
  • 618手机争夺战:5G时代首场大考,荣耀再度领跑
  • outlook qr码在哪里_爱奇艺极速版邀请码是多少在哪里填写 邀请码怎么输入方法...
  • 爱奇艺体育获5亿元战略融资 ,IDG资本、汇盈博润领投
  • 设计模式学习笔记--访问者(Visitor)模式
  • 程序员生涯困惑时的自我解脱
  • C++设计模式23——访问者模式
  • 出现这些情况,裸辞不是找虐,是解脱!
  • C++设计模式——访问者模式
  • 观察者模式与推拉模型
  • 大话设计模式—访问者模式
  • 从细节中解脱
  • 以初学者角度介绍TestComplete的使用
  • 【Kafka】Kafka消费者相关策略
  • 设计模式 : 访问者模式
  • 解决浏览器看不到Flash文档(尤其某慕课)
  • 使用cef3开发的浏览器不支持flash问题的解决
  • ubuntu firefox不能播放MP4,ubuntu Firefox flash 浏览器全屏置顶
  • 使用 Promise 时的5个常见错误
  • 扫地机器人朋友圈文案_最近,一台不务正业的愚大宝扫地机器人火遍朋友圈
  • 全程实操 | 最新版OpenCV4.4免费视频课程送给大家
  • html5学习开发指南
  • 如何设置显示网络计算机,如何在台式计算机上设置无线局域网络

我所知道查找算法之斐波拉契(黄金分割法)查找相关推荐

  1. 查找算法:斐波那契查找算法实现及分析

    斐波那契查找算法介绍 斐波那契查找法肯定与斐波那契相关嘛,斐波那契数列 又称黄金分割数列.所以我们先把黄金分割弄懂,后面代码才能看得懂!黄金分割点大家都知道吧.1:0.618或者1.618:1,我们的 ...

  2. 数据结构与算法-查找算法(二分查找,插值查找,斐波那契(黄金分割法)查找)

    查找算法 以下三种算法的基本思想相同,都是利用递归来寻找 二分查找 思路分析 1.首先确定该数组的中间下标,min = (left + right) / 2 2.然后让需要查找的的数findVal和a ...

  3. 趣学算法之斐波拉契数列实现

    1.斐波拉契数列 f(1) = 1; f(2) = 1; f(3) = f(1) + f(2);以此内推1 x = 1 f(x) = 1 x = 2f(x - 1) + f(x - 2) x > ...

  4. 查找算法之斐波那契查找算法

    斐波那契(黄金分割法)查找算法 (一)算法简介 (1)斐波那契数列 在讲算法之前,我们先介绍一下斐波那契数列,该数列公式为F(K) = F(k-1) + F(k-2),即 1.1.2.3.5.8.13 ...

  5. 【数据结构与算法】插值查找算法、斐波那契查找算法(黄金分割法)的介绍和程序实现

    目录 1. 插值查找算法 1.1 插值查找算法的介绍 1.2 插值查找算法的程序实现 2. 斐波那契查找算法 2.1 斐波那契查找算法的介绍 2.2 斐波那契查找算法的程序实现 1. 插值查找算法 1 ...

  6. 007.斐波拉契查找算法

    1. 斐波拉契查找算法 斐波拉契查找算法也称为黄金分割查找算法,它是在折半查找算法的基础上根据斐波拉契数列进行分割.折半法是取排序好的中间值进行分割,而斐波拉契查找算法是根据黄金分割点进行分割. 黄金 ...

  7. 数据结构三大查找算法(二分查找、插值查找、斐波那契数列查找)C语言实现

    文章目录 查找 二分查找(折半查找) 插值查找 斐波拉契查找 总结: 查找 查找是在大量的信息里面寻找一个特定的信息元素 (1)静态查找和动态查找: 静态或者动态都是针对查找表而言的.动态表指查找表中 ...

  8. 算法导论--斐波那契堆

    斐波那契堆 斐波那契堆也是数据储存结构的一种,这种数据结构之所以产生,主要有两个优点:1.对于数据合并操作具有很高的效率:2.对于其他一般数据操作平均时间复杂度较好(注意这里是平均复杂度,不是最坏情形 ...

  9. 在计算机科学中算法指的是,算法 - 为什么斐波纳契数在计算机科学中具有重要意义?...

    算法 - 为什么斐波纳契数在计算机科学中具有重要意义? Fibonacci数字已经成为计算机科学学生递归的一个流行的介绍,并且有一个强烈的论据,他们坚持在自然界. 出于这些原因,我们很多人都熟悉它们. ...

最新文章

  1. 如何理解LSTM后接CRF?
  2. oracle 10g 手动创建scott(tiger) schema
  3. web前端技术分享:管理系统全栈项目之注册功能
  4. angularjs 让当前路由重新加载_Spring Cloud Gateway的动态路由怎样做?集成Nacos实现很简单...
  5. tengine安装问题
  6. c++中union的使用,看高手们如何解释的
  7. (数据分析三板斧)第一斧Numpy-第二节:生成数组、数组属性和切片
  8. 前端常用插件、工具类库汇总,新手必收藏!!!
  9. 亚马逊与 Uber,软件开发的方式有何不同?
  10. 配置Https 和 HSTS
  11. tomcat按日期分割日志(官网文档推荐实现)
  12. jeecg框架中时间控件时分秒的显示
  13. mescroll.js -- 精致的下拉刷新和上拉加载js框架
  14. MongoDB分片式高可用集群搭建
  15. MySql NTERVAL函数
  16. zabbix_agentd_window端运行报错cannot connect to Service Manager: [0x00000005]
  17. 今年出现了5种电子商务SEO趋势
  18. 民航空管中计算机的应用发展,民航空管网络与信息安全管理体系的构建论文
  19. el-form 验证规则里prop一次验证两个或多个值
  20. Python毕业设计 抖音短视频数据分析与可视化 - python 大数据 可视化

热门文章

  1. 小瓦怕扫地机器人_小瓦扫地机器人青春版app下载-小瓦扫地机器人米家app下载v5.6.81 安卓版-西西软件下载...
  2. 通过js实现图片与文字的转换
  3. java实现can通信_[MicroPython]TPYBoard v102 CAN总线通信
  4. 【常垒·投资】芯率智能完成A轮融资
  5. Linux多窗口终端使用、shell快捷键以及修改快捷键
  6. 阿里云服务器如何防DDOS攻击
  7. 可长时间佩戴的耳机真的存在吗?骨传导耳机是否对耳朵伤害更小?
  8. 学习网络安全一头雾水,想找些学习资料都不知道哪里入手?
  9. ssm项目,测试方法一直转圈,运行不停止
  10. jflash烧录教程_Jlink flash 烧录HEX 程序