查找算法 —— 斐波拉契查找法
一、介绍
斐波拉契查找法是以分割范围进行查找的,分割的方式是按照斐波拉契级数的方式来分割。好处是:只用到加减运算,计算效率较高一些。
要使用斐波拉契查找首先需要定义一颗斐波拉契查找树,建立规则如下:
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)
相关文章:
查找算法 —— 斐波拉契查找法
一、介绍 斐波拉契查找法是以分割范围进行查找的,分割的方式是按照斐波拉契级数的方式来分割。好处是:只用到加减运算,计算效率较高一些。 要使用斐波拉契查找首先需要定义一颗斐波拉契查找树,建立规则如下: 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" 类型的游戏开发通常是指那些在线多人游戏,其特点是快节奏、实时互动和简单的玩法。这些游戏的名字通常以 ".io" 结尾,如 "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 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 基于深度学习的数学公式识别算法实现 该项目较为新颖,适合作为竞赛课题方向,学…...
Pikachu靶场——跨站请求伪造(CSRF)
文章目录 1. 跨站请求伪造(CSRF)1.1 CSRF(get)1.2 CSRF(post)1.3 CSRF Token1.4 CSRF漏洞防御 1. 跨站请求伪造(CSRF) 还可以参考我的另一篇文章:跨站请求伪造(CSRF) 全称Cross-site request forgery,翻译…...
软件测试简历项目经验怎么写?大厂面试手拿把掐
前言 在写简历之前,我们先来看看失败者的简历和成功者的简历之间有什么区别。为什么成功者的简历可以在求职中起到“四两拨千斤”的作用,而失败者的简历却被丢进了垃圾桶,这两者到底有什么不同? 成功的简历与失败的简历 我们发现…...
图像处理与计算机视觉--第七章-神经网络-单层感知器
文章目录 1.单层感知器原理介绍2.单层感知器算法流程3.单层感知器算法实现4.单层感知器效果展示5.参考文章与致谢 1.单层感知器原理介绍 1.单层感知器是感知器中最简单的一种,有单个神经元组成的单层感知器只能用于解决线性可分的二分性问题2.在空间中如果输入的数据…...
pyserial,win11,串口总是被占用
之前哪里看到的忘记了,记录: win11,用pyserial这个库,打开COM后,程序退出,关闭串口,下次打开仍然会报错。每次都要拔串口线,很烦。 去设备管理器里,把usb串口线的驱动页…...
网站上线如何检查?
网站上线如何检查?很多企业搭建好网站之后,不知道如何检查网站,其实网站上线之后,要对网站的代码,网站的SEO细节,等重要因素检查,下面我们就来讲述一下企业优化网站建站、上线检查要求。 网站上线如何检查…...
如何理解pytorch中的“with torch.no_grad()”?
torch.no_grad()方法就像一个循环,其中循环中的每个张量都将requires_grad设置为False。这意味着,当前与当前计算图相连的具有梯度的张量现在与当前图分离了我们将不再能够计算关于该张量的梯度。直到张量在循环内,它才与当前图分离。一旦用梯…...
Linux虚拟机克隆之后使用ip addr无法获取ip地址
Linux虚拟机克隆之后使用ip addr无法获取ip地址 因为克隆得到的虚拟机,与原先的linux系统是一模一样的包括MAC地址和IP地址。需要修改信息。 设置IP地址: 使用vi命令打开linux的网卡 //ifcfg-enth0是虚拟网卡的名称,如果你的不叫这个名字&a…...
日报系统:优化能源行业管理与决策的利器
日报系统:优化能源行业管理与决策的利器 引言: 随着能源行业的快速发展和复杂性增加,管理各个部门的数据变得至关重要。为了提高运营效率和决策的准确性,能源行业普遍采用日报系统作为综合数据汇报和分析的工具。本文将探讨日报系…...
linux安装idea
下载好之后是.tar.gz文件后缀的 使用命令解压安装包 tar -zxvf 你的安装包 解压好了之后进入解压好的目录找到bin文件里的idea.sh,使用命令启动它 ./idea.sh 这样你就可以在manjaro上使用idea了 在这里插入图片描述 需要手动创建快捷启动方式 每次都使用命令行启动是比较…...
vue启动项目,npm run dev出现error:0308010C:digital envelope routines::unsupported
运行vue项目,npm run dev的时候出现不支持错误error:0308010C:digital envelope routines::unsupported。 在网上找了很多,大部分都是因为版本问题,修改环境之类的,原因是对的但是大多还是没能解决。经过摸索终于解决了。 方法如…...
vue-devtools插件安装
拓展程序连接 链接:https://pan.baidu.com/s/1tEyZJUCEK_PHPGhU_cu_MQ?pwdr2cj 提取码:r2cj 一、打开谷歌浏览器,点击扩展程序-管理扩展程序 二、打开开发者模式,将vue-devtools.crx 拖入页面,点击添加扩展程序 成…...
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,而JAVA使用Websocket时,Websocket一定会有个onOpen方法。 ClientEndpoint public class WebsocketListener {OnOpenpublic void onOpen(Session session) throws IOException {}OnMessagepublic void onMessage(ByteBuffer byteBuff…...
VMware中Ubuntu(Linux)无法连接网络解决办法记录
问题: 操作系统:Ubuntu 22.04.3 LTS VMware 版本:VMware Workstation 17 Pro, 17.0.0 build-20800274今天在虚拟机用Ubuntu的时候,发现无法连接网络,如下: wdwd-virtual-machine:~$ ifconfig lo: flags73…...
第19节 Node.js Express 框架
Express 是一个为Node.js设计的web开发框架,它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用,和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...
Java 语言特性(面试系列1)
一、面向对象编程 1. 封装(Encapsulation) 定义:将数据(属性)和操作数据的方法绑定在一起,通过访问控制符(private、protected、public)隐藏内部实现细节。示例: public …...
postgresql|数据库|只读用户的创建和删除(备忘)
CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...
现代密码学 | 椭圆曲线密码学—附py代码
Elliptic Curve Cryptography 椭圆曲线密码学(ECC)是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础,例如椭圆曲线数字签…...
从零实现STL哈希容器:unordered_map/unordered_set封装详解
本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说,直接开始吧! 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...
自然语言处理——循环神经网络
自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元(GRU)长短期记忆神经网络(LSTM)…...
mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包
文章目录 现象:mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时,可能是因为以下几个原因:1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...
嵌入式学习笔记DAY33(网络编程——TCP)
一、网络架构 C/S (client/server 客户端/服务器):由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序,负责提供用户界面和交互逻辑 ,接收用户输入,向服务器发送请求,并展示服务…...
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要: 近期,在使用较新版本的OpenSSH客户端连接老旧SSH服务器时,会遇到 "no matching key exchange method found", "n…...
