搜索算法系列之四(斐波那契)

以下算法被验证过,如有什么问题或有补充的欢迎留言。

前言

斐波那契数列,又称黄金分割数列,是由意大利数学家(Leonardo Fibonacci)在1202年提出的。这个数列的递推关系是F(0)=1,F(1)=1,F(n)=F(n-1)+F(n-2)(n≥2,n∈N*),即每一项都是前两项的和。

斐波那契数列在自然界、数学、物理、工程技术和艺术等多个领域都有广泛的应用。

算法原理

斐波那契搜索算法是一种基于斐波那契数列的分割搜索技术,旨在优化查找过程的效率。它的原理可以概括如下:

  1. 斐波那契数列的选择

    • 首先,我们需要选择一个斐波那契数列,这个数列的长度应该比待搜索数组的长度略大。通常,选择的斐波那契数列是递增的,并且长度满足斐波那契数列的定义:每个数字是前两个数字之和。
  2. 计算斐波那契数列中的两个相邻数

    • 根据选定的斐波那契数列,计算相邻的两个斐波那契数列值,记为 fib1fib2
  3. 定义偏移量和搜索范围

    • 初始时,定义一个偏移量 offset 为 -1,表示初始搜索范围为整个数组。
    • 定义搜索范围的上限为 fib1n - 1 中较小的一个。
  4. 开始搜索

    • 在每一轮的搜索中,比较当前偏移量加上 fib2 的位置处的元素与待搜索的关键字。
    • 如果当前位置处的元素小于关键字,则说明关键字可能在当前位置的右侧,因此将搜索范围限制在右侧,并更新偏移量和斐波那契数列值。
    • 如果当前位置处的元素大于关键字,则说明关键字可能在当前位置的左侧,因此将搜索范围限制在左侧,并更新偏移量和斐波那契数列值。
    • 如果当前位置处的元素等于关键字,则搜索成功,返回当前位置的索引。
  5. 迭代搜索

    • 继续以上步骤,直到搜索范围缩小到只包含一个元素,或者直到找到关键字为止。

斐波那契搜索算法的核心思想在于通过斐波那契数列来定义搜索范围的分割点,从而实现更高效的搜索过程。与二分搜索类似,它也是一种分治策略,但相对于二分搜索,斐波那契搜索算法在某些情况下具有更好的效率,特别是当搜索的数组长度不是 2 的幂次方时。

代码实现(c)

#include <stdio.h>// 定义斐波那契搜索算法
int fibonacciSearch(int arr[], int n, int key) {int fib2 = 0; // (m-2)th Fibonacci numberint fib1 = 1; // (m-1)th Fibonacci numberint fib = fib1 + fib2; // mth Fibonacci number// 找到斐波那契数列中最接近数组长度的数while (fib < n) {fib2 = fib1;fib1 = fib;fib = fib1 + fib2;}int offset = -1; // 偏移量while (fib > 1) {int i = (offset + fib2) < (n - 1) ? (offset + fib2) : (n - 1);if (arr[i] < key) {fib = fib1;fib1 = fib2;fib2 = fib - fib1;offset = i;} else if (arr[i] > key) {fib = fib2;fib1 = fib1 - fib2;fib2 = fib - fib1;} else {return i; // 找到了,返回索引}}// 没有找到return -1;
}int main() {int arr[] = { 10, 22, 35, 40, 45, 50, 80, 82, 85, 90, 100 };int n = sizeof(arr) / sizeof(arr[0]);int key = 45;int index = fibonacciSearch(arr, n, key);if (index != -1) {printf("找到了数字 %d ,位于索引 %d 处。\n", key, index);} else {printf("未找到数字 %d 。\n", key);}return 0;
}

示例演示

说明假设:基于1的索引。目标元素x为85。阵列的长度n=11。
最小的斐波那契数大于或等于11是13。如图所示,fibMm2=5、fibMm1=8和fibM=13。
另一个实现细节是偏移量变量(初始化为零)。它标志着已经被淘汰的范围,从前面开始。我们将不定期更新它。
现在,由于offset值是一个索引,并且包括它和它下面的所有索引都已被消除,所以只需要向它添加一些东西。由于fibMm2标记了大约三分之一的数组,以及它标记的索引,肯定是有效的,我们可以将fibMm2添加到offset中,并检查索引i=min(offset+fibMm2,n)处的元素。

优点与局限性

优点:

  1. 时间复杂度较低: 斐波那契查找的时间复杂度为 O(log n),与二分查找一样,具有较高的查找效率。
  2. 适用性广泛: 与二分查找类似,斐波那契查找适用于有序数组,可以用于查找静态数据集。
  3. 比较次数较少: 在一些情况下,斐波那契查找比二分查找的比较次数更少,因此对于大型数据集或者查找次数较多的情况下,斐波那契查找可能更优。

缺点:

  1. 空间复杂度较高: 斐波那契查找需要额外的空间来存储斐波那契数列,因此在空间受限的情况下可能不太适用。
  2. 实现较复杂: 相对于简单的二分查找,斐波那契查找的实现较为复杂,需要计算斐波那契数列,并且需要考虑多个边界条件。
  3. 对数据结构要求高: 斐波那契查找要求数据集必须是有序的,对数据的插入、删除等操作会导致数据集无序,因此不太适用于动态数据集。

实际应用

https://www.mitrade.com/cn/insights/others/technical-analysis/fibonacci#/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/320068.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在Android中,如何通过Kotlin协程处理多个API调用

在Android中&#xff0c;如何通过Kotlin协程处理多个API调用 在Android开发中&#xff0c;如何使用Kotlin协程处理多个API调用的示例呢&#xff1f;假设我们已经对Kotlin协程有了一定的了解&#xff0c;包括定义、简单用例和示例等。现在&#xff0c;让我们来看一些真实的Andr…

[Java、Android面试]_22_APP启动流程(中频问答)

欢迎查看合集&#xff1a; Java、Android面试高频系列文章合集 本人今年参加了很多面试&#xff0c;也有幸拿到了一些大厂的offer&#xff0c;整理了众多面试资料&#xff0c;后续还会分享众多面试资料。 整理成了面试系列&#xff0c;由于时间有限&#xff0c;每天整理一点&am…

LVS/NAT工作模式介绍及配置

1.1 LVS/NAT模式工作原理 LVS&#xff08;Linux Virtual Server&#xff09;的网络地址转换&#xff08;NAT&#xff09;模式是一种在网络层&#xff08;第四层&#xff09;实现负载均衡的方法。在NAT模式中&#xff0c;Director Server&#xff08;DS&#xff09;充当所有服务…

Python 全栈系列241 GFGo Lite迭代

说明 随着整个算网开发逐渐深入&#xff0c;各个组件、微服务的数量、深度在不断增加。由于算网是个人项目&#xff0c;我一直按照MVP(Minimum Viable Product )的原则在推进。由于最初的时候对架构、算法和业务的理解并没有那么深刻&#xff0c;所以MVP的内容还是在不断变化&…

【高阶数据结构】并查集

并查集 并查集1、概念2、根据人找编号 / 根据编号找人&#xff08;简单介绍一下并查集&#xff09;&#xff08;1&#xff09;代码展示&#xff08;2&#xff09;调试结果 3、并查集操作和演示题目&#xff08;1&#xff09;并查集操作i、思路ii、总体代码 &#xff08;2&#…

Tokitsukaze and Average of Substring

原题链接&#xff1a;登录—专业IT笔试面试备考平台_牛客网 目录 1. 题目描述 2. 思路分析 3. 代码实现 1. 题目描述 2. 思路分析 前缀和。 开一个int类型的前缀和数组pre[30][N]&#xff08;pre[i][j]表示某字符转成的数字 i 在一段区间的前缀个数。因为字母表有‘a’~z…

【Unity 组件思想-预制体】

【Unity 组件思想-预制体】 预制体&#xff08;Prefab&#xff09;是Unity中一种特殊的组件 特点和用途&#xff1a; 重用性&#xff1a; 预制体允许开发者创建可重复使用的自定义游戏对象。这意味着你可以创建一个预制体&#xff0c;然后在场景中多次实例化它&#xff0c;…

猿人学第七题-动态字体-随风漂移

前言&#xff1a;该题主要是考对fontTools.ttLib.TTFont的操作&#xff0c;另外就是对字典互相映射的操作 一、woff文件存储 from fontTools.ttLib import TTFont #pip install fontTools def save_woff(response):woff response[woff]woff_file base64.b64decode(woff.enc…

Java Jackson-jr 库是干什么用的

Jackson-jr 是一个轻量级的Java JSON 处理库。这个库被设计用来替代 Jackson 的复杂性。对比 Jackson 的复杂 API&#xff0c;Jackson-jr 的启动速度更快&#xff0c;包大小更小。 虽然Jackson databind&#xff08;如ObjectMapper&#xff09;是通用数据绑定的良好选择&#…

uniapp动态设置Tabbar

一套小程序及app可能会有多个用户角色&#xff0c;多者能看到的内容应该是不一样的。 实现原理 舍弃uniapp原生的tabbar&#xff0c;使用uView插件下的u-tabbar导航插件来实现。介绍 | uView 2.0 - 全面兼容 nvue 的 uni-app 生态框架 - uni-app UI 框架uView UI&#xff0c;是…

JavaScript百炼成仙自学笔记——2

一、循环遍历&#xff1a; 方式一 for(var i0;i<10;i){console.log(i); }方式二 var i 0; while(i < 100){console.log(i);i; }细看代码就是 先定义变量i&#xff0c;再执行{}中的代码&#xff0c;最后改循环变量的值 二、遍历 什么事遍历&#xff1f; 什么时候会用…

CMakeLists.txt语法规则:部分常用命令说明四

一. 简介 前面几篇文章学习了CMakeLists.txt语法中前面几篇文章学习了CMakeLists.txt语法中部分常用命令。文章如下&#xff1a; CMakeLists.txt语法规则&#xff1a;部分常用命令说明一-CSDN博客 CMakeLists.txt语法规则&#xff1a;部分常用命令说明二-CSDN博客 CMakeLi…

基于springboot+vue+Mysql的自习室预订系统

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…

谈谈Tcpserver开启多线程并发处理遇到的问题!

最近在学习最基础的socket网络编程&#xff0c;在Tcpserver开启多线程并发处理时遇到了一些问题&#xff01; 说明 在linux以及Windows的共享文件夹进行编写的&#xff0c;所以代码中有的部分使用 #ifdef WIN64 ... #else ... #endif 进入正题&#xff01;&#xff01;&…

Unity Navigation 入门(新版)

概述 在游戏的制作过程中&#xff0c;寻路功能一定是非常重要的部分&#xff0c;他可以为主角寻路&#xff0c;也可以运用到敌人追击等&#xff0c;相比于自己实现的难度&#xff0c;使用寻路组件就显得简单的多&#xff0c;那接下来就开始学习这部分的内容吧 1.安装AI Naviga…

MySQL 运维篇

回顾基本语句&#xff1a; 数据定义语言(DDL) 这类语言用于定义和修改数据库的结构&#xff0c;包括创建、删除和修改数据库、 表、视图和索引等对象。 主要的语句关键字包括 CREATE 、 DROP 、 ALTER 、 RENAME 、 TRUNCATE 等。 create database 数据库 &#xff1b; cr…

关于AIGC发展历程的研究报告(原创文章)

摘要&#xff1a; 2022年&#xff0c;Chat GPT和Stable Diffusion展现了AIGC强大的技术实力&#xff0c;拉开了AIGC时代的帷幕。2023年&#xff0c;GPT-4、Midjourney V5等又掀起了人工智能的热潮&#xff0c;2024年2月15日&#xff08;美国当地时间&#xff09;正式对外发布的…

代码随想录day51 | 动态规划P12 | ● 309. ● 714. ●买卖股票总结

309.最佳买卖股票时机含冷冻期 给定一个整数数组 prices&#xff0c;其中第 prices[i] 表示第 i 天的股票价格 。​ 设计一个算法计算出最大利润。在满足以下约束条件下&#xff0c;你可以尽可能地完成更多的交易&#xff08;多次买卖一支股票&#xff09;: 卖出股票后&…

《21天学通C++》(第十一章)多态

为什么需要多态&#xff1f; 为了最大限度地减少代码&#xff0c;提高可读性 1.虚函数 虚函数是C中的一种特殊成员函数&#xff0c;它允许在派生类&#xff08;也称为子类&#xff09;中重写&#xff08;覆盖&#xff09;基类的实现&#xff0c;使用virtual进行声明 在C中&am…