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

news2024/12/23 23:10:07

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

前言

斐波那契数列,又称黄金分割数列,是由意大利数学家(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 number
    int fib1 = 1; // (m-1)th Fibonacci number
    int 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.coloradmin.cn/o/1646276.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

微搭低代码入门05文件的上传和下载

目录 1 创建数据源2 创建应用3 创建页面4 设置导航功能5 文件上传6 文件下载总结 小程序中&#xff0c;我们通常会有文件的上传和下载的需&#xff0c;在微搭中&#xff0c;文件是存放在云存储中&#xff0c;每一个文件都会有一个唯一的fileid&#xff0c;我们本篇就介绍如何通…

强化学习玩flappy_bird

强化学习玩flappy_bird&#xff08;代码解析&#xff09; 游戏地址&#xff1a;https://flappybird.io/ 该游戏的规则是&#xff1a; 点击屏幕则小鸟立即获得向上速度。 不点击屏幕则小鸟受重力加速度影响逐渐掉落。 小鸟碰到地面会死亡&#xff0c;碰到水管会死亡。&#…

vscode连接服务器的docker步骤

进入容器之后&#xff0c;操作方式与本地windows系统操作逻辑一样&#xff1b;容器内部结构都能任意查看和使用&#xff0c;创建文件及编写python脚本都可以直接使用vs code编辑器进行编辑和调试&#xff0c;从而避免使用命令行及vim编辑文件&#xff0c;非常直观且方便~

4. RedHat认证-进程管理

4. RedHat认证-进程管理 1.进程概念 进程就是正在运行中的程序或者命令 每一个进程都是运行的实体&#xff0c;都有自己的地址空间&#xff0c;并占有一定的资源空间 程序消耗的是磁盘资源、进程消耗的是内存和CPU资源 进程会占用四类资源&#xff08;CPU 、内存、磁盘、网…

python爬虫(一)之 抓取极氪网站汽车文章

极氪汽车文章爬虫 闲来没事&#xff0c;将极氪网站的汽车文章吃干抹尽&#xff0c;全部抓取到本地&#xff0c;还是有点小小的难度。不能抓取太快&#xff0c;太快容易被封禁IP&#xff0c;不过就算被封了问题也不大&#xff0c;大不了重启路由器&#xff0c;然后你的IP里面又…

i.MX 6ULL 裸机 IAR 环境安装

一. IAR 的安装请自行搜索 二. 使用最新版本的 IAR&#xff0c;需要修改 SDK 1. 在 SDK 的 core_ca7.h 加上 #include "intrinsics.h" /* IAR Intrinsics */ 2. debug 时需要修改每个工程下的 ddr_init.jlinkscript&#xff0c;参考链接 Solved: How to conn…

使用C语言实现杨氏矩阵并找出数字

前言 过了五一假期&#xff0c;咋们经过了一个假期的休息&#xff0c;要继续学习了&#xff0c;不能偷懒哦&#xff01;&#xff01; 今天让我们来看看如何在一个杨氏矩阵中找出自己想找到的数字。 首先&#xff0c;我们要了解一下杨氏矩阵到底是什么&#xff0c;如果一个矩阵中…

[redis] redis为什么快

1. Redis与Memcached的区别 两者都是非关系型内存键值数据库&#xff0c;现在公司一般都是用 Redis 来实现缓存&#xff0c;而且 Redis 自身也越来越强大了&#xff01;Redis 与 Memcached 主要有以下不同&#xff1a; (1) memcached所有的值均是简单的字符串&#xff0c;red…

ACPWorkbench_for_BP10

一、菜单 文件菜单包含导入导出所有参数&#xff0c;导出flashbin文件和退出操作。文件菜单显示如下&#xff1a; Import Audio Settings&#xff1a;从音频配置文件中导入音频参数。 Export Audio Settings&#xff1a;将音频设置导出为音频配置文件。 Export Flash Binary Fi…

OpenNJet:下一代云原生应用引擎

OpenNJet&#xff1a;下一代云原生应用引擎 前言一、技术架构二、新增特性1. 透明流量劫持2. 熔断机制3. 遥测与故障注入 三、Ubuntu 发行版安装 OpentNJet1. 添加gpg 文件2. 添加APT 源3. 安装及启动4. 验证 总结 前言 OpenNJet&#xff0c;是一款基于强大的 NGINX 技术栈构建…

设置定位坐标+请按任意键继续

设置定位坐标 目的 在编程和游戏开发中&#xff0c;设置定位坐标的目的是为了确定对象在屏幕或游戏世界中的具体位置。坐标通常由一对数值表示&#xff0c;例如 (x, y)&#xff0c;其中 x 表示水平位置&#xff0c;y 表示垂直位置。设置定位坐标的目的包括&#xff1a; 1. **精…

【JavaScript】数据类型转换

JavaScript 中的数据类型转换主要包括两种&#xff1a;隐式类型转换&#xff08;Implicit Type Conversion&#xff09;和显式类型转换&#xff08;Explicit Type Conversion&#xff09;。 1. 隐式类型转换&#xff08;自动转换&#xff09;&#xff1a; js 是动态语言&…

CNN笔记详解

CNN(卷积神经网络) 计算机视觉&#xff0c;当你们听到这一概念的是否好奇计算机到底是怎样知道这个图片是什么的呢&#xff1f;为此提出了卷积神经网络&#xff0c;通过卷积神经网络&#xff0c;计算机就可以识别出图片中的特征&#xff0c;从而识别出图片中的物体。看到这里充…

XYCTF2024 RE ez unity 复现

dll依然有加壳 但是这次global-metadata.dat也加密了&#xff0c;原工具没办法用了&#xff0c;不过依然是可以修复的 a. 法一&#xff1a;frida-il2cpp-bridge 可以用frida-il2cpp-bridge GitHub - vfsfitvnm/frida-il2cpp-bridge: A Frida module to dump, trace or hijac…

深度剖析muduo网络库1.1---面试提问(阻塞、非阻塞、同步、异步)

在面试过程中&#xff0c;如果被问到关于IO的阻塞、非阻塞、同步、异步时&#xff0c;我们应该如何回答呢&#xff1f; 结合最近学习的课程&#xff0c;我作出了以下的总结&#xff0c;希望能与大家共同探讨&#xff01; 先给出 陈硕大神原话&#xff1a;在处理IO的时候&…

存储故障后oracle报—ORA-01122/ORA-01207故障处理---惜分飞

客户存储异常,通过硬件恢复解决存储故障之后,oracle数据库无法正常启动(存储cache丢失),尝试recover数据库报ORA-00283 ORA-01122 ORA-01110 ORA-01207错误 以前处理过比较类似的存储故障case:又一起存储故障导致ORA-00333 ORA-00312恢复存储故障,强制拉库报ORA-600 kcbzib_kcr…

计算机毕设

随着社会和国家的重视&#xff0c;大学对于大学生毕业设计越来越重视。 做软件设计设计方面&#xff0c;前后端分离是必不可少的&#xff0c;代码管理工具&#xff0c;前后端接口测试是项目中必须要用到的工具。做大数据设计方面&#xff0c;主要是要用到爬虫进行数据爬取&…

(二)JSP教程——taglib指令

创建标签文件 首先创建一个Web项目&#xff0c;在webapp/WEB-INF目录下创建一个tags文件夹 在tags文件夹中创建一个oddNumberSum.tag文件&#xff0c;Tag文件时扩展名为.tag的文本文件&#xff0c;其结构和JSP文件非常相似&#xff0c;该文件的目录结构如图所示 创建Tag文件的…

Altium Designer——检查原理图库正确性并生成报告

一、方法&#xff1a; 1.打开原理图库&#xff1a; 2.点击菜单栏的报告选项&#xff1a; 3.选择器件规则检查&#xff1a; 根据需求勾选&#xff0c;一般都是全部勾选&#xff1a; 二、问题&#xff1a; 1.缺少封装会导致什么问题&#xff1a; 1.首先&#xff1a; 封装是…

方法的入栈和出栈

一.作用域问题 1.全局作用域 在全局都能进行访问的变量 var a 10;function fn() {var b 20;return a b;}console.log(fn()); 2.局部的作用域 只能在限定的范围内进行访问 function fn() {var b 20;}console.log(b); b is not defined 打印的结果是b这个变量没用定义 3…