一、斐波那契查找算法基本思想

斐波那契查找算法又称为黄金分割法查找算法,是一种有序查找算法

斐波那契数列,又称黄金分割数列,指的是这样一个数列: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(log2n)

斐波那契查找原理与二分查找和插值查找相似,仅仅改变了中间结点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 。该式说明:只要顺序表的长度为F[k]-1,则可以将该表分成长度为F[k-1]-1和F[k-2]-1的两段,即如上图所示。从而中间位置为mid=low+F(k-1)-1;
(2)每一子段也可以用相同的方式分割;
(3)若顺序表长度n不一定刚好等于F[k]-1,则需要将原来的顺序表长度n增加至F[k]-1。这里的k值只要能使得F[k]-1恰好大于或等于n即可。

例如:原数组为{1,5,6,33,55,233,455},长度n为7,若 F[ k ] - 1等于9,则应该将原数组扩容到9,多出的位置使用high位置的455填充,即得到{1,5,6,33,55,233,455,455,455}。

二、代码实现

斐波拉契查找算法实现思路:

(1)我们需要先递归实现斐波拉契数列,然后根据原数组的大小计算斐波拉契数列的k值;
(2)数组扩容条件是:增大 k 值(索引从 0 开始),使得数组长度刚好大于或者等于斐波那契数列中的 F[k]-1 ,我们定义临时数组 temp ,temp 后面为 0 的元素都按照数组最大元素值填充
(3)mid值的确定:mid = low + f[k - 1] - 1 ,即用黄金分割点确定 mid 的值;
(4)value<temp[mid] :目标值在黄金分割点的左边,因为全部元素 = 前面的元素 + 后边元素即 f[k] = f[k-1] + f[k-2],又前面有 f[k-1]个元素,所以可以继续拆分 f[k-1] = f[k-2] + f[k-3],即下次循环有mid=low+f[k-1-1]+1,即需要k-=1
value> temp[mid] :目标值在黄金分割点的右边。因为全部元素 = 前面的元素 + 后边元素即 f[k] = f[k-1] + f[k-2],又前面有 f[k-2]个元素,所以可以继续拆分 f[k-1] = f[k-3] + f[k-4],即下次循环有mid=low+f[k-1-2]+1,即需要k-=2
value== temp[mid] :找到目标值,因为数组经历过扩容,后面的值其实有些是多余的,mid 可能会越界(相对于原数组来说)则有:
1)mid <= high :证明 mid 索引在原数组中,返回 mid
2)mid > high 时,证明 mid 索引已经越界(相对于原数组来说),返回 high
(5)若没有找到则返回-1。

package Search;import java.util.Arrays;
import java.util.Scanner;public class FibonacciSearch {public static final int maxSize=20;//斐波拉契数列的大小public static int[] fibonacci() {//构造斐波拉契数列int[] fib=new int[maxSize];fib[0]=1;fib[1]=1;for(int i=2;i<maxSize;i++) {fib[i]=fib[i-1]+fib[i-2];}return fib;}public static int fibonaccisearch(int[] arr,int value) {int low=0;//指针low表示待查元素所在范围的下界,下界索引从0开始int high=arr.length-1;//指针high表示待查元素所在范围的上界int k=0;//表示斐波那契分割数值的下标int mid=0;int fib[]=fibonacci();//获取到斐波那契数列while(high>fib[k]-1) {//获取到斐波那契分割数值的下标k++;}int[] temp=Arrays.copyOf(arr, fib[k]);//因为f[k]值 可能大于a的 长度,因此我们需要使用Arrays.copyOf方法,构造一个新的数组,并指向temp[]for(int i=high+1;i<temp.length;i++) {//使用arr数组最后的数填充 temptemp[i]=arr[high];}while(low<high) {mid=low+fib[k-1]-1;//斐波拉契中间值公式if(value<temp[mid]) {//关键字值小于中间值,应该向左扫描即使high=mid-1high=mid-1;k-=1;}else if(value>temp[mid]) {//关键字值大于中间值,应该向右扫描即使low=mid+1low=mid+1;k-=2;}else {//找到时需要确定返回哪个下标if(mid<=high) {//证明mid索引在原数组中,返回 midreturn mid;}else {//证明mid索引已经越界(相对于原数组来说),返回 highreturn high;}}}return -1;//没有找到即返回-1}public static void main(String[] args) {int[] arr= {1,5,6,33,55,233,455};Arrays.sort(arr);//采用斐波拉契查找时,数据需是有序不重复的,需要对该数组进行排序Scanner sc=new Scanner(System.in);System.out.println("请输入查找元素:");int value=sc.nextInt();System.out.printf("查找元素 %d 的位置是 %d",value,fibonaccisearch(arr,value));}
}

运行结果:

请输入查找元素:
55
查找元素 55 的位置是 4

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

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

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

  2. 斐波那契数列的迭代算法和递归算法

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

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

    斐波那契(黄金分割法)查找算法: 斐波那契(黄金分割法)原理:**斐波那契查找**原理与前两种相似,仅仅改变了中间结点(mid)的位置,mid不再是中间或插值位于黄金割点附近,即==**mid=low ...

  4. python编写递归函数和非递归函数、输出斐波那契数列_python 入门之斐波那契数列递归表达式算法和非递归算法...

    题目: 斐波那契数列是一组有规律的数列:1,1,2,3,5,8,13,--..,那么我们怎么用python 来完成此算法,并求出第200位的值是多少 1.python 递归表达式实现: def fib ...

  5. 斐波那契数列-爬楼梯算法

    爬楼梯算法 有n级楼梯,有2种爬法,1次1级,或1次2级,问,n级楼梯有多少种爬法? 递归求解 首先,当只有一阶楼梯的时候,很显然只有一种走法:有两阶楼梯的时候,也很显然的知道有两种走法.就会有下面这 ...

  6. 斐波那契数列(Fibonacci) - 这就是算法吗?爱了爱了

    斐波那契数列(Fibonacci) 今天开始做牛客的剑指Offie,一看到斐波那契我就想到递归,是它是它就是它,然后我就满怀期待地写下了下面地代码.ok,没问题,一次性过.然而,我滴老天鹅,才击败30 ...

  7. 求解斐波那契数列(Fibonacci Numbers)算法居然有9种,你知道哪几种吗?

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

  8. 斐波那契数列两种算法实现(循环,递归)

    首先是最简单的递归算法,相信很多初学者第一次接触递归这种算法都是从写一个斐波那契数列开始的. 这里除了递归算法之外我还会介绍循环算法 首先是最基础的递归算法 #include <stdio.h& ...

  9. 【js算法】js斐波那契数列的多种算法

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

  10. 用python函数写斐波那契数列非递归,python 入门之斐波那契数列递归表达式算法和非递归算法...

    题目: 斐波那契数列是一组有规律的数列:1,1,2,3,5,8,13,........,那么我们怎么用python 来完成此算法,并求出第200位的值是多少 1.python 递归表达式实现: def ...

最新文章

  1. LCD MIPI DSI时钟计算
  2. 6 岁!是时候重新认识下 Serverless 了
  3. mysql bitmap redis_Redis中bitmap的妙用
  4. 使用母版頁是內容如何使用CSS和javascript(轉)
  5. Java学习笔记之:Java引用数据类型之字符串
  6. Primefaces,Hibernate和SpringRoo集成
  7. jquery中checkbox赋值
  8. windows 2003内存设置
  9. 三维人体姿态估计年度进展综述(周晓巍教授)
  10. 全新微头像V2.1.8版全套iApp源码分享
  11. “互联网+”大学生创新创业大赛项目策划书
  12. Python-开根号的几种方式
  13. 从下单到享用,美团外卖背后的分布式架构设计
  14. 【计算机组成原理】学习笔记----第一章 计算机系统概述
  15. 支付宝小程序设置服务器维护,教程|如何开发支付宝小程序服务端:蚂蚁金融云...
  16. c#文件名去掉后缀_C# 怎么去掉文件名后缀
  17. 微信小程序,不可不知的一二三四
  18. 【学习】手写数字生成
  19. 华强北山寨“AirPods 3”出圈,油管博主直夸好
  20. the jar file has no source attachment解决方法

热门文章

  1. mysql 误删表 恢复数据_MySQL误删数据或者误清空表恢复
  2. ACM中AC、WA、PE、RE分别是什么意思
  3. 计算机工程制图电子书,程计算机制图工程计算机制图.pdf
  4. 向iPhone模拟器中添加视频
  5. 基于OpenCV3.0的车牌识别系统设计(二)--车牌提取
  6. php怎么把图片设置为背景,ppt怎么把图片设为背景
  7. SUBMAIL API如何帮助您构建企业云通信平台?
  8. PhotoShop 各历史版本
  9. 显著性检测(二)Spatio-temporal Saliency Detection Using Phase Spectrum of Quaternion Fourier Transform
  10. 电脑小鸟壁纸怎么彻底删除?