当前位置: 首页 > news >正文

查找算法 —— 斐波拉契查找法

一、介绍

        斐波拉契查找法是以分割范围进行查找的,分割的方式是按照斐波拉契级数的方式来分割。好处是:只用到加减运算,计算效率较高一些。

       要使用斐波拉契查找首先需要定义一颗斐波拉契查找树,建立规则如下:

       1.斐波拉契树的左右子树均为斐波拉契树。

       2.当数据个数n确定时,若想确定斐波拉契树的层数k值,就必须找到一个最小的K值,使得斐波拉契层数的Fib(k+1)>= n+1.

       3.斐波拉契树的树根一定是一个斐波拉契树,且子节点与父节点差值的绝对值为斐波拉契数。

       4.当k>=2时,斐波拉契树的树根为Fib(k),左子树为(k-1)层斐波拉契树(其树根为Fib(k-1)),

右子树为(k-2)层斐波拉契树(其树根为Fib(k) + Fib(k-2))。

       5.若n+1的值不为斐波拉契数的值,则可以找出存在一个m使用Fib(k+1)-m = n+1,m=Fib(k+1)-(n+1),再按斐波拉契树的建立原则完成斐波拉契树的建立,最后斐波拉契树的各节点减去差值m即可,并把小于1的节点去掉。

      可以先罗列一部分斐波拉契数的值,如下:

 Fib(0) = 0, Fib(1) = 1, Fib(2) = 1, Fib(3) =2, Fib(4) = 3,

 Fib(5) = 5, Fib(6) = 8, Fib(7) = 13,  Fib(8) = 21, Fib(9) = 34,

      接下来第一种情况时n+1的值是斐波拉契数的值,假设就是数1~33,也就是n=33,那么n+1 = 34,可以根据Fib(k+1) >= n+1 得出 k的值为8,则可以建立斐波拉契树,如下:       

  第二种情况就是n+1的值不是斐波拉契数的值,假设n=10,那么n+1 =11,不是斐波拉契数,按照第五条规则,可以找出一个值m,使Fib(k+1) - m = n+1成立,则Fib(k+1)=13,则m=2, k=6,按照规则建立的斐波拉契树如下:

各节点减去m,并把小于1的节点去掉之后得到

斐波拉契查找法步骤首先将要查找的数与树根Fib(k)比较,如果相等这个数就是Fib(k),如果比Fib(k)小则,数在1到Fib(k)-1之间,如果比Fib(k)大,则这个数在Fib(k)+1到Fib(k+1)-1之间。

二、建立Fib树代码

1.首先先生成Fib数储存起来,避免每次查找都要计算一遍:

void FibCalc(int n)
{   fibls.Add(0);for (int i = 1; i < n; i++){if (i < 3){fibls.Add(1);}else{fibls.Add(fibls[i-1] + fibls[i-2]);} }
}

2.然后判断一个数是不是Fib数并且找到一个比这个数大或者相等的Fib数

 bool LookUpFibAndIsFib(int val, out int ksum1){ksum1 = -1;if (val < 0){Debug.LogError("输入的值不能小于0");return false;}for (int i = 0; i < fibls.Count; i++){if (val == fibls[i]){ksum1 = i;return true;}else if(val < fibls[i]){ksum1 = i;return false;}}Debug.LogError("没有匹配到K");return false;}

 3,生成Fib树

  void GenerateFibTree(Node node, int k,int val){if (k - 2 < 0) return;int fibNum = node.Data - fibls[k - 2];if (fibNum == node.Data) return;if (node.Data != 1){node.LeftNode = new Node();node.LeftNode.Data = fibNum;node.LeftNode.PNode = node;}int fibNumR = node.Data + fibls[k - 2];if (fibNum > 1 && fibNumR != root.Data){if (fibNumR != node.PNode.Data || node.PNode == null){if (node.PNode.PNode != null && fibNumR != node.PNode.PNode.Data){node.RightNode = new Node();node.RightNode.Data = fibNumR;node.RightNode.PNode = node;}if (node.PNode.PNode == null){node.RightNode = new Node();node.RightNode.Data = fibNumR;node.RightNode.PNode = node;}}}if (node.LeftNode != null)GenerateFibTree(node.LeftNode, k - 1, val);if (node.RightNode != null)GenerateFibTree(node.RightNode, k - 2, val);}

 4.在需要减去m的情况下:

 void FibTreeMinusM(int m,Node node){if (node.LeftNode != null){node.LeftNode.Data -= m;FibTreeMinusM(m, node.LeftNode);if (node.LeftNode.Data < 1)node.LeftNode = null;}if (node.RightNode != null){node.RightNode.Data -= m;FibTreeMinusM(m, node.RightNode);if (node.RightNode.Data < 1)node.RightNode = null;}}

5.最后按照输入的数值生成Fib树

   void FibLookUpArithmetic(int val){int ksum1 = 0;if (LookUpFibAndIsFib(val+1, out ksum1)){int k = ksum1 - 1;InitGenerateFibTree(k,val);}else{int k = ksum1 - 1;InitGenerateFibTree(k, val);int m = fibls[ksum1] - (val + 1);root.Data -= m;FibTreeMinusM(m, root);}}

 完整代码:

using System.Collections.Generic;
using UnityEditor.Experimental.GraphView;
using UnityEngine;
using UnityEngine.Rendering;public class LookUpArithmetic : MonoBehaviour
{List<int> fibls;Node root;void Start(){fibls = new List<int>(30);FibCalc(30);FibLookUpArithmetic(10);}void FibLookUpArithmetic(int val){int ksum1 = 0;if (LookUpFibAndIsFib(val+1, out ksum1)){int k = ksum1 - 1;InitGenerateFibTree(k,val);}else{int k = ksum1 - 1;InitGenerateFibTree(k, val);int m = fibls[ksum1] - (val + 1);root.Data -= m;FibTreeMinusM(m, root);}}bool LookUpFibAndIsFib(int val, out int ksum1){//首先判断是否是一个Fbi数和找到一个Fbi数两步可以合并为一步ksum1 = -1;if (val < 0){Debug.LogError("输入的值不能小于0");return false;}for (int i = 0; i < fibls.Count; i++){if (val == fibls[i]){ksum1 = i;return true;}else if(val < fibls[i]){ksum1 = i;return false;}}Debug.LogError("没有匹配到K");return false;}void FibCalc(int n){   fibls.Add(0);for (int i = 1; i < n; i++){if (i < 3){fibls.Add(1);}else{fibls.Add(fibls[i-1] + fibls[i-2]);} }}void InitGenerateFibTree(int k, int val){root = new Node();root.Data = fibls[k];root.LeftNode = new Node();root.LeftNode.Data = fibls[k] - fibls[k - 2];root.LeftNode.PNode= root;GenerateFibTree(root.LeftNode, k - 1, val);root.RightNode = new Node();root.RightNode.Data = fibls[k] + fibls[k - 2];root.RightNode.PNode = root;GenerateFibTree(root.RightNode, k - 2, val);}void GenerateFibTree(Node node, int k,int val){if (k - 2 < 0) return;int fibNum = node.Data - fibls[k - 2];if (fibNum == node.Data) return;if (node.Data != 1){node.LeftNode = new Node();node.LeftNode.Data = fibNum;node.LeftNode.PNode = node;}int fibNumR = node.Data + fibls[k - 2];if (fibNum > 1 && fibNumR != root.Data){if (fibNumR != node.PNode.Data || node.PNode == null){if (node.PNode.PNode != null && fibNumR != node.PNode.PNode.Data){node.RightNode = new Node();node.RightNode.Data = fibNumR;node.RightNode.PNode = node;}if (node.PNode.PNode == null){node.RightNode = new Node();node.RightNode.Data = fibNumR;node.RightNode.PNode = node;}}}if (node.LeftNode != null)GenerateFibTree(node.LeftNode, k - 1, val);if (node.RightNode != null)GenerateFibTree(node.RightNode, k - 2, val);}void FibTreeMinusM(int m,Node node){if (node.LeftNode != null){node.LeftNode.Data -= m;FibTreeMinusM(m, node.LeftNode);if (node.LeftNode.Data < 1)node.LeftNode = null;}if (node.RightNode != null){node.RightNode.Data -= m;FibTreeMinusM(m, node.RightNode);if (node.RightNode.Data < 1)node.RightNode = null;}}
}class Node
{public Node LeftNode;public Node RightNode;public int Data;public Node PNode = null;
}

如有不足之处,欢迎指正。

参考书籍:

清华大学出版社-图书详情-《图解数据结构--使用C#》 (tsinghua.edu.cn)

相关文章:

查找算法 —— 斐波拉契查找法

一、介绍 斐波拉契查找法是以分割范围进行查找的&#xff0c;分割的方式是按照斐波拉契级数的方式来分割。好处是&#xff1a;只用到加减运算&#xff0c;计算效率较高一些。 要使用斐波拉契查找首先需要定义一颗斐波拉契查找树&#xff0c;建立规则如下&#xff1a; 1.斐波拉契…...

PL/SQL全量同步

全量同步 -- 实现逻辑:用源表的数据直接覆盖目标表 -- 插入数据前:先清空目标表,然后查询源表的数据,插入目标表 -- 1. 先创建一个目标表 CREATE TABLE EMP_T AS SELECT E.*, SYSDATE CREATE_DATE, SYSDATE UPDATE_DATE, SYSDATE ETL_DATE FROM EMP E WHERE 12;SELECT * FR…...

IO类型游戏研发定制开发

"IO" 类型的游戏开发通常是指那些在线多人游戏&#xff0c;其特点是快节奏、实时互动和简单的玩法。这些游戏的名字通常以 ".io" 结尾&#xff0c;如 "Agar.io"、"Slither.io" 等。如果您有兴趣进行 "IO" 类型游戏的研发或提…...

Eclipse iceoryx(千字自传)

1 在固定时间内实现无任何限制的数据传输 在汽车automotive、机器人robotics和游戏gaming等领域,必须在系统的不同部分之间传输大量数据。使用Linux等操作系统时,必须使用进程间通信(IPC)机制传输数据。Eclipse iceoryx是一种中间件,它使用零拷贝Zero-Copy、共享内存Share…...

竞赛 深度学习 opencv python 公式识别(图像识别 机器视觉)

文章目录 0 前言1 课题说明2 效果展示3 具体实现4 关键代码实现5 算法综合效果6 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 基于深度学习的数学公式识别算法实现 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;学…...

Pikachu靶场——跨站请求伪造(CSRF)

文章目录 1. 跨站请求伪造&#xff08;CSRF&#xff09;1.1 CSRF(get)1.2 CSRF(post)1.3 CSRF Token1.4 CSRF漏洞防御 1. 跨站请求伪造&#xff08;CSRF&#xff09; 还可以参考我的另一篇文章&#xff1a;跨站请求伪造(CSRF) 全称Cross-site request forgery&#xff0c;翻译…...

软件测试简历项目经验怎么写?大厂面试手拿把掐

前言 在写简历之前&#xff0c;我们先来看看失败者的简历和成功者的简历之间有什么区别。为什么成功者的简历可以在求职中起到“四两拨千斤”的作用&#xff0c;而失败者的简历却被丢进了垃圾桶&#xff0c;这两者到底有什么不同&#xff1f; 成功的简历与失败的简历 我们发现…...

图像处理与计算机视觉--第七章-神经网络-单层感知器

文章目录 1.单层感知器原理介绍2.单层感知器算法流程3.单层感知器算法实现4.单层感知器效果展示5.参考文章与致谢 1.单层感知器原理介绍 1.单层感知器是感知器中最简单的一种&#xff0c;有单个神经元组成的单层感知器只能用于解决线性可分的二分性问题2.在空间中如果输入的数据…...

pyserial,win11,串口总是被占用

之前哪里看到的忘记了&#xff0c;记录&#xff1a; win11&#xff0c;用pyserial这个库&#xff0c;打开COM后&#xff0c;程序退出&#xff0c;关闭串口&#xff0c;下次打开仍然会报错。每次都要拔串口线&#xff0c;很烦。 去设备管理器里&#xff0c;把usb串口线的驱动页…...

网站上线如何检查?

网站上线如何检查?很多企业搭建好网站之后&#xff0c;不知道如何检查网站&#xff0c;其实网站上线之后&#xff0c;要对网站的代码&#xff0c;网站的SEO细节&#xff0c;等重要因素检查&#xff0c;下面我们就来讲述一下企业优化网站建站、上线检查要求。 网站上线如何检查…...

如何理解pytorch中的“with torch.no_grad()”?

torch.no_grad()方法就像一个循环&#xff0c;其中循环中的每个张量都将requires_grad设置为False。这意味着&#xff0c;当前与当前计算图相连的具有梯度的张量现在与当前图分离了我们将不再能够计算关于该张量的梯度。直到张量在循环内&#xff0c;它才与当前图分离。一旦用梯…...

Linux虚拟机克隆之后使用ip addr无法获取ip地址

Linux虚拟机克隆之后使用ip addr无法获取ip地址 因为克隆得到的虚拟机&#xff0c;与原先的linux系统是一模一样的包括MAC地址和IP地址。需要修改信息。 设置IP地址&#xff1a; 使用vi命令打开linux的网卡 //ifcfg-enth0是虚拟网卡的名称&#xff0c;如果你的不叫这个名字&a…...

日报系统:优化能源行业管理与决策的利器

日报系统&#xff1a;优化能源行业管理与决策的利器 引言&#xff1a; 随着能源行业的快速发展和复杂性增加&#xff0c;管理各个部门的数据变得至关重要。为了提高运营效率和决策的准确性&#xff0c;能源行业普遍采用日报系统作为综合数据汇报和分析的工具。本文将探讨日报系…...

linux安装idea

下载好之后是.tar.gz文件后缀的 使用命令解压安装包 tar -zxvf 你的安装包 解压好了之后进入解压好的目录找到bin文件里的idea.sh,使用命令启动它 ./idea.sh 这样你就可以在manjaro上使用idea了 在这里插入图片描述 需要手动创建快捷启动方式 每次都使用命令行启动是比较…...

vue启动项目,npm run dev出现error:0308010C:digital envelope routines::unsupported

运行vue项目&#xff0c;npm run dev的时候出现不支持错误error:0308010C:digital envelope routines::unsupported。 在网上找了很多&#xff0c;大部分都是因为版本问题&#xff0c;修改环境之类的&#xff0c;原因是对的但是大多还是没能解决。经过摸索终于解决了。 方法如…...

vue-devtools插件安装

拓展程序连接 链接&#xff1a;https://pan.baidu.com/s/1tEyZJUCEK_PHPGhU_cu_MQ?pwdr2cj 提取码&#xff1a;r2cj 一、打开谷歌浏览器&#xff0c;点击扩展程序-管理扩展程序 二、打开开发者模式&#xff0c;将vue-devtools.crx 拖入页面&#xff0c;点击添加扩展程序 成…...

const关键字

目录 修饰指针 指向常量的指针*ptr 指针常量:数据类型 * const 指针变量 修饰引用 const &...

HTML5+CSS3+JS小实例:仿优酷视频轮播图

实例:仿优酷视频轮播图 技术栈:HTML+CSS+JS 效果: 源码: 【html】 <!DOCTYPE html> <html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"><meta name="viewport" content=&quo…...

dart的Websocket为什么找不到onOpen方法?

我主要使用的是JAVA&#xff0c;而JAVA使用Websocket时&#xff0c;Websocket一定会有个onOpen方法。 ClientEndpoint public class WebsocketListener {OnOpenpublic void onOpen(Session session) throws IOException {}OnMessagepublic void onMessage(ByteBuffer byteBuff…...

VMware中Ubuntu(Linux)无法连接网络解决办法记录

问题&#xff1a; 操作系统&#xff1a;Ubuntu 22.04.3 LTS VMware 版本&#xff1a;VMware Workstation 17 Pro, 17.0.0 build-20800274今天在虚拟机用Ubuntu的时候&#xff0c;发现无法连接网络&#xff0c;如下&#xff1a; wdwd-virtual-machine:~$ ifconfig lo: flags73…...

企业信息采集神器:10分钟掌握天眼查企查查双平台爬虫

企业信息采集神器&#xff1a;10分钟掌握天眼查&企查查双平台爬虫 【免费下载链接】company-crawler 天眼查爬虫&企查查爬虫&#xff0c;指定关键字爬取公司信息 项目地址: https://gitcode.com/gh_mirrors/co/company-crawler 还在为获取企业信息而烦恼吗&…...

基于CircuitPython的电机动态性能测试系统:从原理到实践

1. 项目概述与核心价值搞电机驱动&#xff0c;最怕的就是“凭感觉”。你手上有个直流有刷电机&#xff0c;数据手册上写着空载转速12000转&#xff0c;堵转扭矩50mNm&#xff0c;但实际装到你的机器人关节或者小车上&#xff0c;带上传动机构&#xff0c;性能到底怎么样&#x…...

2026年实测推荐:10款思维导图工具,开发者效率翻倍

作为技术博主&#xff0c;我常年用思维导图拆解需求、梳理架构、记录学习笔记。2026年&#xff0c;工具们卷出了新高度&#xff1a;AI辅助、白板一体化、实时协作成了标配。本文从开发者视角出发&#xff0c;实测了10款热门工具&#xff0c;帮你选出最适合的那把“瑞士军刀”。…...

Workerman-todpole 部署实战:Linux/Windows 环境配置与优化技巧 [特殊字符]

Workerman-todpole 部署实战&#xff1a;Linux/Windows 环境配置与优化技巧 &#x1f680; 【免费下载链接】workerman-todpole HTML5WebSocketPHP(Workerman) , rumpetroll server writen using php 项目地址: https://gitcode.com/gh_mirrors/wo/workerman-todpole Wo…...

嵌入式TFT屏幕LVGL驱动适配:从硬件抽象到性能优化的全流程实践

1. 项目概述与核心价值最近在几个嵌入式显示项目里&#xff0c;我深度折腾了TFT屏幕与LVGL的适配工作。这活儿听起来像是把两个现成的轮子装到一起&#xff0c;但真上手了才发现&#xff0c;从点亮屏幕到丝滑流畅的UI交互&#xff0c;中间隔着不少“坑”。如果你也在为STM32、E…...

3分钟解锁CAJ文件:如何将知网专属格式转换为可搜索PDF

3分钟解锁CAJ文件&#xff1a;如何将知网专属格式转换为可搜索PDF 【免费下载链接】caj2pdf Convert CAJ (China Academic Journals) files to PDF. 转换中国知网 CAJ 格式文献为 PDF。佛系转换&#xff0c;成功与否&#xff0c;皆是玄学。 项目地址: https://gitcode.com/gh…...

从绿光到算法:深入解析PPG信号检测的核心技术与实践挑战

1. 绿光背后的秘密&#xff1a;为什么PPG传感器偏爱这种颜色 你可能已经注意到&#xff0c;市面上大多数智能手表的心率监测功能都会发出幽幽的绿光。这可不是为了好看——绿光在PPG&#xff08;光电容积脉搏波&#xff09;技术中扮演着关键角色。让我用一个简单的比喻来解释&…...

告别手动切号!全栈实战:用AI辅助编写一个「多平台海量私信秒回」系统

最近在研究全网营销和客资管理系统&#xff0c;看到这样两张产品宣传图&#xff0c;直击痛点&#xff1a;一个工作台&#xff0c;快速处理海量私信/评论&#xff08;告别多个聊天窗口来回切换&#xff09;。7x24小时在线&#xff0c;AI秒回客户&#xff08;告别响应时间长、客户…...

为 Claude Code 配置 Taotoken 以解决访问不稳定与 Token 不足问题

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 为 Claude Code 配置 Taotoken 以解决访问不稳定与 Token 不足问题 Claude Code 作为一款强大的编程助手&#xff0c;其原生服务有…...

Verilog时钟分频:从原理到工程实践,避坑指南与最佳方案

1. 项目概述&#xff1a;为什么时钟分频是数字设计的基石在数字电路和FPGA设计里&#xff0c;时钟信号就像是整个系统的心跳。它驱动着寄存器、状态机和数据流&#xff0c;确保所有操作在正确的节拍下同步进行。但现实情况是&#xff0c;我们手头的时钟源往往只有一个固定的频率…...