斐波拉契搜索(费氏搜寻法)分析与实现

2024-02-24 18:30

本文主要是介绍斐波拉契搜索(费氏搜寻法)分析与实现,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

要说斐波拉契搜索就必须要先说一下什么 是斐波拉契数列:

斐波拉契数列:
F(1)=1,
F(2)=1,
F(n)=F(n-1)+F(n-2)(n>=3,n∈N*)
就是从第三项开始,每一项都等于前两项的和。

费氏搜寻法简介:
费氏搜寻法,就是利用斐波拉契数列从有序数列中搜寻特定元素的一种搜索算法,它的前提是数列必须要有序。我们熟悉的二分查询,每次搜寻的时候,都会讲区间分为两半,所以其搜寻时间为O(log(2)n),这边要介绍的费氏搜索,其利用费氏数列中的数作为间隔来搜寻下一个数,所以区间收敛的速度会更快,搜索时间为O(logn)。

用一个例子来说明:

查询的数组:num[]
0 0 1 1 1 2 2 2 3 5 6 7 8 8 9
斐波拉契数列:F[]
1 1 2 3 5 8 13 21…

现在假定我们查询的数字是:find=7.
方便计算,我们的num[]和F[]的数组下标都从1开始。
首先,可以知道数组num长度n=15,先找到(尽可能大的)小于等于15的F[x]=13,他的下标x=7,此时还需要一个公式:F[x]+m=n,所以m=15-13=2;
x,m,F[x]在一开始数组长度知道的情况下就可以知道了。

第一次搜索:
不是从x=7,开始查询的,而是x–,i=x=6开始查询的,如果num[6]<7,这时候,i+=m,第二次搜索的时候就从第8个开始。(如果num[6]>7,则i是i-=F[x])
i=6 num[6]=2<7 i+=2

第二次搜索:
第二次搜索就从上一次 得出的i=8开始搜索,这时候,num[8]=2<7,这时候i的变化不再是加减m了,而是加减斐波拉契数列的值(F[x])了。num[i]小于我们要查找的数值,i就加斐波拉契数列的值,反之则减.
i=8 num[8]=2<7 i+=F[–x] 即i+=F[5] i=8+5=13

第三次搜索

i=13 num[13]=8>7 i-=F[–x] 即i-=F[4] i=13-3=10

第四次搜索:
i=10 num[10]=5<7 i+=F[–x] 即i+=F[3] i=10+2=12

第五次搜索:
i=12 num[12]=7 这样就找到我们要查找的数值7,他是索引12.

总结:
费氏搜寻会先透过公式计算求出第一个要搜寻数的位置,F[x]+m=n,计算出F[x],m,x的值,用费氏数列作为间隔来搜寻下一个数,区间收敛的速度更快,同时本身只会用到加减法,在运算上也可以加快。

代码:

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define MAX 15
#define SWAP(x,y) {int t; t = x; x = y; y = t;}void createfib(void);               // 建立费氏数列
int findx(int);                     // 找x值
int fibsearch(int[], int);          // 费氏搜寻
void quicksort(int[], int, int);    // 快速排序int Fib[MAX] = {-999};//主程序(C/OC)int main(void){int number[MAX] = {0};
int i, find;srand(time(NULL));for(i = 1; i <= MAX; i++) {     //产生随机数列number[i] = rand() % 10;
}quicksort(number, 1, MAX);      //快速排序printf("数列:");                //打印排序后的数列
for(i = 1; i <= MAX; i++)printf("%d ", number[i]);
find = 7;                      //要寻找的对象
if((i = fibsearch(number, find)) >= 0)printf("找到数字于索引 %d ", i);
elseprintf("\n找不到指定数");printf("\n"); 
}
//建立费氏数列,总共求得MAX+1个斐波那契数
void createfib(void) {int i;Fib[0] = 0;Fib[1] = 1;for(i = 2; i < MAX; i++)Fib[i] = Fib[i-1] + Fib[i-2];
}//找x值
int findx(int n) {int i = 0;while(Fib[i] <= n)i++;i--;return i;//找到第i个Fib元素小于等于MAX+1
}//费式搜寻
int fibsearch(int number[], int find) {int i, x, m;createfib();                    //创建斐波那契数列x  = findx(MAX+1);              //斐波那契数列中第x个数刚好不大于MAX+1。MAX是确定的,所以比较的起始点是确定的。m = MAX - Fib[x];               //得到一个较小的差值。m的值也是确定的。printf("\nx = %d, m = %d, Fib[x] = %d\n\n",x, m, Fib[x]);x--;i = x;if(number[i] < find)            //i的初值也是确定的。i += m;while(Fib[x] > 0) {             //搜寻,x值不断减小,范围越来越小,搜寻越来越精细if(number[i] < find)        //小于被搜寻的值i += Fib[--x];          //右移搜寻位置else if(number[i] > find)   //大于被搜寻值i -= Fib[--x];          //左移搜寻位置elsereturn i;               //相等,找到}return -1;                      //搜寻步子已经最小,还是没找到,搜寻结束
}//快速排序
void quicksort(int number[], int left, int right) {int i, j, k, s;if(left < right) {s = number[(left+right)/2];i = left - 1;j = right + 1;while(1) {while(number[++i] < s) ;        // 向右找while(number[--j] > s) ;        // 向左找if(i >= j)break;SWAP(number[i], number[j]);}quicksort(number, left, i-1);       // 对左边进行递回quicksort(number, j+1, right);      // 对右边进行递回} 
} 

运行结果:
在这里插入图片描述

这篇关于斐波拉契搜索(费氏搜寻法)分析与实现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/742977

相关文章

C++对象布局及多态实现探索之内存布局(整理的很多链接)

本文通过观察对象的内存布局,跟踪函数调用的汇编代码。分析了C++对象内存的布局情况,虚函数的执行方式,以及虚继承,等等 文章链接:http://dev.yesky.com/254/2191254.shtml      论C/C++函数间动态内存的传递 (2005-07-30)   当你涉及到C/C++的核心编程的时候,你会无止境地与内存管理打交道。 文章链接:http://dev.yesky

[职场] 公务员的利弊分析 #知识分享#经验分享#其他

公务员的利弊分析     公务员作为一种稳定的职业选择,一直备受人们的关注。然而,就像任何其他职业一样,公务员职位也有其利与弊。本文将对公务员的利弊进行分析,帮助读者更好地了解这一职业的特点。 利: 1. 稳定的职业:公务员职位通常具有较高的稳定性,一旦进入公务员队伍,往往可以享受到稳定的工作环境和薪资待遇。这对于那些追求稳定的人来说,是一个很大的优势。 2. 薪资福利优厚:公务员的薪资和

通过SSH隧道实现通过远程服务器上外网

搭建隧道 autossh -M 0 -f -D 1080 -C -N user1@remotehost##验证隧道是否生效,查看1080端口是否启动netstat -tuln | grep 1080## 测试ssh 隧道是否生效curl -x socks5h://127.0.0.1:1080 -I http://www.github.com 将autossh 设置为服务,隧道开机启动

时序预测 | MATLAB实现LSTM时间序列未来多步预测-递归预测

时序预测 | MATLAB实现LSTM时间序列未来多步预测-递归预测 目录 时序预测 | MATLAB实现LSTM时间序列未来多步预测-递归预测基本介绍程序设计参考资料 基本介绍 MATLAB实现LSTM时间序列未来多步预测-递归预测。LSTM是一种含有LSTM区块(blocks)或其他的一种类神经网络,文献或其他资料中LSTM区块可能被描述成智能网络单元,因为

vue项目集成CanvasEditor实现Word在线编辑器

CanvasEditor实现Word在线编辑器 官网文档:https://hufe.club/canvas-editor-docs/guide/schema.html 源码地址:https://github.com/Hufe921/canvas-editor 前提声明: 由于CanvasEditor目前不支持vue、react 等框架开箱即用版,所以需要我们去Git下载源码,拿到其中两个主

android一键分享功能部分实现

为什么叫做部分实现呢,其实是我只实现一部分的分享。如新浪微博,那还有没去实现的是微信分享。还有一部分奇怪的问题:我QQ分享跟QQ空间的分享功能,我都没配置key那些都是原本集成就有的key也可以实现分享,谁清楚的麻烦详解下。 实现分享功能我们可以去www.mob.com这个网站集成。免费的,而且还有短信验证功能。等这分享研究完后就研究下短信验证功能。 开始实现步骤(新浪分享,以下是本人自己实现

基于Springboot + vue 的抗疫物质管理系统的设计与实现

目录 📚 前言 📑摘要 📑系统流程 📚 系统架构设计 📚 数据库设计 📚 系统功能的具体实现    💬 系统登录注册 系统登录 登录界面   用户添加  💬 抗疫列表展示模块     区域信息管理 添加物资详情 抗疫物资列表展示 抗疫物资申请 抗疫物资审核 ✒️ 源码实现 💖 源码获取 😁 联系方式 📚 前言 📑博客主页:

探索蓝牙协议的奥秘:用ESP32实现高质量蓝牙音频传输

蓝牙(Bluetooth)是一种短距离无线通信技术,广泛应用于各种电子设备之间的数据传输。自1994年由爱立信公司首次提出以来,蓝牙技术已经经历了多个版本的更新和改进。本文将详细介绍蓝牙协议,并通过一个具体的项目——使用ESP32实现蓝牙音频传输,来展示蓝牙协议的实际应用及其优点。 蓝牙协议概述 蓝牙协议栈 蓝牙协议栈是蓝牙技术的核心,定义了蓝牙设备之间如何进行通信。蓝牙协议

python实现最简单循环神经网络(RNNs)

Recurrent Neural Networks(RNNs) 的模型: 上图中红色部分是输入向量。文本、单词、数据都是输入,在网络里都以向量的形式进行表示。 绿色部分是隐藏向量。是加工处理过程。 蓝色部分是输出向量。 python代码表示如下: rnn = RNN()y = rnn.step(x) # x为输入向量,y为输出向量 RNNs神经网络由神经元组成, python

高度内卷下,企业如何通过VOC(客户之声)做好竞争分析?

VOC,即客户之声,是一种通过收集和分析客户反馈、需求和期望,来洞察市场趋势和竞争对手动态的方法。在高度内卷的市场环境下,VOC不仅能够帮助企业了解客户的真实需求,还能为企业提供宝贵的竞争情报,助力企业在竞争中占据有利地位。 那么,企业该如何通过VOC(客户之声)做好竞争分析呢?深圳天行健企业管理咨询公司解析如下: 首先,要建立完善的VOC收集机制。这包括通过线上渠道(如社交媒体、官网留言