【数据结构与算法】斐波那契查找(黄金分割法)

news/2024/5/22 3:54:03

斐波那契查找(黄金分割法)

黄金分割点是指把一条线段分割成两部分,使其中一部分与全长之比等于另一部分与这部分之比。取其前三位数字的近似值是 0.618。由于按此比例设计的造型十分美丽,因此称为黄金分割,也称为中外比。这是一个神奇的数字,会带来意想不到的效果。

斐波那契数列 {1,1,2,3,5,8,13,21,34,55} 发现斐波那契数列的两个相邻数的比例,无限接近于黄金分割值 0.618。

斐波那契(黄金分割法)原理

斐波那契查找原理与二分查找和插值查找相似,仅仅改变了中间结点(mid)的位置,mid 不再是中间或者插值得到,而是位于黄金分割点附近,即 mid = lift + F(k - 1) - 1 (F代表斐波那契数列)

在这里插入图片描述

对 F(k - 1) - 1 的理解:

  1. 由斐波那契数列 F[k] = F[k - 1] + F[k - 2] 的性质,可以看到 (F[k] - 1) = (F[k - 1] - 1) + (F[k - 2] - 1) + 1。该式说明:只要顺序表的长度为 F[k] - 1,则可以将该表分成长度为 F[k - 1] - 1 和 F[k - 2] - 1 的两段,即如上图所示。从中间的位置为 mid = lift + F(k - 1) - 1
  2. 类似的,每一子段也可以用相同的方式分割
  3. 但顺序表长度 n 不一定刚好等于 F[k] - 1,所以需要将原来的顺序表长度 n 增加至 F[k] - 1。这里的 k 值只要能使得 F[k] - 1 恰好大于或等于 n 即可,由以下代码得到,顺序表长度增加后,新增的位置(从 n + 1 到 F[k] - 1 位置),都赋为 n 位置的值即可。
while(n > fib(k) - 1) {k++;
}

代码演示:

public class FibonacciSearch {public static int maxSize = 20;public static void main(String[] args) {int[] arr = {1, 8, 10, 89, 1000, 1234};System.out.println("index = " + fibSearch(arr, 89));}// 因为后面我们 mid = low + F(k - 1) - 1,需要使用斐波那契数列,因此我们需要获得一个斐波那契数列// 非递归方法得到一个斐波那契数列public static int[] fib() {int[] f = new int[maxSize];f[0] = 1;f[1] = 1;for (int i = 2; i < maxSize; i++) {f[i] = f[i - 1] + f[i - 2];}return f;}/*** 编写斐波那契查找算法* 使用非递归的方式编写算法** @param a   数组* @param key 我们需要查找的关键码(值)* @return 返回对应下标,如果没有返回 -1*/public static int fibSearch(int[] a, int key) {int low = 0;int high = a.length - 1;int k = 0; // 表示斐波那契分割数值的下标int mid = 0; // 存放 mid 值int[] f = fib(); // 获取斐波那契数组// 获取到斐波那契分割数值的下标while (high > f[k] - 1) {k++;}// 因为 f[k] 值可能大于 a 的长度,因此我们需要使用 Arrays 类,构造一个新的数组,并指向 a[]// 不足的部分会使用 0 填充int[] temp = Arrays.copyOf(a, f[k]);// 实际上需要使用 a 数组的最后的数填充 temp// 举例:temp = {1, 8, 10, 89, 1000, 1234, 0, 0, 0} => {1, 8, 10, 89, 1000, 1234, 1234, 1234, 1234}for (int i = high + 1; i < temp.length; i++) {temp[i] = a[high];}// 使用 while 循环处理,找到我们的数 keywhile (low <= high) { // 只要这个条件满足,就可以找mid = low + f[k - 1] - 1;if (key < temp[mid]) { // 我们应该继续向数组的前面查找(左边)high = mid - 1;// 为什么是 k--;// 说明// 1. 全部元素 = 前面的元素 + 后面的元素// 2. f[k] = f[k - 1] + f[k - 2]// 3. 因为前面有 f[k - 1] 个元素,所以乐意继续拆分 f[k - 1] = f[k - 2] + f[k - 3]// 4. 即 在 f[k - 1] 的前面继续查找 k--// 5. 即下次循环 mid = f[k - 1 - 1] - 1k--;} else if (key > temp[mid]) { // 我们应该继续向数组的后面查找(右边)low = mid + 1;// 为什么是 k -= 2;// 说明// 1. 全部元素 = 前面的元素 + 后面的元素// 2. f[k] = f[k - 1] + f[k - 2]// 3. 因为后面有 f[k - 2] 个元素,所以乐意继续拆分 f[k - 1] = f[k - 3] + f[k - 4]// 4. 即 在 f[k - 2] 的前面继续查找 k-= 2// 5. 即下次循环 mid = f[k - 1 - 2] - 1k -= 2;} else { // 找到// 需要确定返回的是哪个下标if (mid <= high) {return mid;} else {return high;}}}return -1;}
}

http://www.mrgr.cn/p/66570340

相关文章

人工智能安全-2-非平衡数据处理

0 提纲 现象与原因非平衡数据处理方法概览数据预处理层面特征层算法层面1 现象与原因 非平衡数据分类问题:在网络信息安全问题中,诸如恶意软件检测、SQL注入、不良信息检测等许多问题都可以归结为机器学习分类问题。这类机器学习应用问题中,普遍存在非平衡数据的现象。 产…

Spring MVC拦截器和跨域请求

一、拦截器简介 SpringMVC的拦截器&#xff08;Interceptor&#xff09;也是AOP思想的一种实现方式。它与Servlet的过滤器&#xff08;Filter&#xff09;功能类似&#xff0c;主要用于拦截用户的请求并做相应的处理&#xff0c;通常应用在权限验证、记录请求信息的日志、判断用…

618技术揭秘 - 大促弹窗搭投实践 | 京东云技术团队

背景 618 大促来了&#xff0c;对于业务团队来说&#xff0c;最重要的事情莫过于各种大促营销。如会场、直播带货、频道内营销等等。而弹窗作为一个极其重要的强触达营销工具&#xff0c;通常用来渲染大促氛围、引流主会场、以及通过频道活动来提升频道复访等。因此&#xff0…

管理ceph集群

文章目录 ceph的常用命令查看集群状态查看pg的状态查看mon节点状态查看osd的通用命令查看osd的容量查看osd池写入文件测试查看池的属性查看文件映射过程 添加磁盘删除磁盘 ceph的常用命令 查看集群状态 ceph osd pool application enable pool-name rbd #将池启用rbd功能 ceph…

华为数通HCIA-网络模型

TCP 网络通信模式 作用&#xff1a;指导网络设备的通信&#xff1b; OSI七层模型&#xff1a; 7.应用层&#xff1a;由应用层协议&#xff08;http、FTP、Telnet.&#xff09;为应用程序产生对应的数据&#xff1b; 6.表示层&#xff1a;将应用层产生的数据转换成网络设备看…

实战:Docker+Jenkins+Gitee构建CICD流水线

文章目录 前言Jenkins部署创建Jenkins docker-compose配置maven源启动Jenkins容器安装插件Gitee ssh公匙配置与测试项目提交 Jenkins创建流水线写在最后 前言 持续集成和持续交付一直是当下流行的开发运维方式&#xff0c;CICD省去了大量的运维时间&#xff0c;也能够提高开发…

【Linux】关于Bad magic number in super-block 当尝试打开/dev/sda1 时找不到有效的文件系统超级块

每个区段与 superblock 的信息都可以使用 dumpe2fs 这个指令来查询的&#xff01; 不过可惜的是&#xff0c;我们的 CentOS 7 现在是以 xfs 为默认文件系统&#xff0c; 所以目前你的系统应该无法使用 dumpe2fs 去查询任何文件系统的。 因为目前两个版本系统的根目录使用的文…

redis基础总结(数据类型)

Redis十大数据类型 String String 是redis最基本数据类型,一个key对应一个value. String类型是二进制安全的,意思是Redis的string类型可以包含任何数据,比如jpg图片或者序列化的对象; String类型是最基本的数据类型,一个redis中字符串value最多是512M; String类型在redis底层…

力扣天天练--week3-LeetCode75

topic75-9-t443:压缩字符串 题目描述&#xff1a; 给你一个字符数组 chars &#xff0c;请使用下述算法压缩&#xff1a; 从一个空字符串 s 开始。对于 chars 中的每组 连续重复字符 &#xff1a; 如果这一组长度为 1 &#xff0c;则将字符追加到 s 中。 否则&#xff0c;需…

企业知识文档管理+群晖nas安全云存储

企业知识管理系统&#xff0c;利用软件系统或其他工具的企业管理方法&#xff0c;利用软件系统或其他工具&#xff0c;对组织中大量的有价值的方案、策划、成果、经验等知识进行分类存储和管理&#xff0c;积累知识资产避免流失&#xff0c;促进知识的学习、共享、培训、再利用…

C++ ——STL容器【list】模拟实现

代码仓库&#xff1a; list模拟实现 list源码 数据结构——双向链表 文章目录 &#x1f347;1. 节点结构体&#x1f348;2. list成员&#x1f349;3. 迭代器模板&#x1f34a;4. 迭代器&#x1f34b;5. 插入删除操作&#x1f34c;5.1 insert & erase&#x1f34c;5.2 push_…

【C++】开源:跨平台轻量日志库easyloggingpp

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍跨平台轻量日志库easyloggingpp。 无专精则不能成&#xff0c;无涉猎则不能通。。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&am…

论文笔记--GloVe: Global Vectors for Word Representation

论文笔记--GloVe: Global Vectors for Word Representation 1. 文章简介2. 文章概括3 文章重点技术3.1 两种常用的单词向量训练方法3.2 GloVe3.3 模型的复杂度 4. 文章亮点5. 原文传送门6. References 1. 文章简介 标题&#xff1a;GloVe: Global Vectors for Word Representa…

<MySQL> Centos 7环境安装MySQL

Centos 7环境安装MySQL 1.卸载不要的环境 停止MySQL服务 systemctl stop mariadb.service systemctl stop mysqld禁止MySQL服务开机自启 systemctl disable mysqld卸载MySQL软件包 yum remove mysql-server mysql-client删除MySQL数据目录 rm -rf /var/lib/mysql清理MySQ…

安装了pyintaller后出现:‘pyinstaller‘ 不是内部或外部命令,也不是可运行的程序或批处理文件。

2023年7月31日&#xff0c;周一上午 我昨天晚上也遇到了这个问题&#xff0c;后来解决了 目录 出错原因解决方法怎么找到Scripts文件夹 出错原因 出现这个错误是因为你没给python的Scripts文件夹添加环境变量&#xff0c; Scripts存放着pip安装包时产生的可执行文件。 解决…

CentOS下 Docker、Docker Compose 的安装教程

Docker 是一个开源的应用容器引擎&#xff0c;让开发者可以打包他们的应用以及依赖包到一个可移植的容器中&#xff0c;然后发布到任何流行的 Linux 机器上&#xff0c;也可以实现虚拟化。容器是完全使用沙箱机制&#xff0c;相互之间不会有任何接口。 Docker Compose是用于定义…

如何启用路由器dhcp?快解析如何内网穿透?

一、什么是DHCP&#xff1f; 动态主机设置协议&#xff08;DHCP&#xff09;是一种使网络管理员能够集中管理和自动分配 IP 网络地址的通信协议。在网络中&#xff0c;每个联网设备都需要分配独有的 IP 地址。并当有新计算机移到网络中的其它位置时&#xff0c;能自动收到新的…

百度文心一言接入教程-Java版

原文链接 前言 前段时间由于种种原因我的AI BOT网站停运了数天&#xff0c;后来申请了百度的文心一言和阿里的通义千问开放接口&#xff0c;文心一言的接口很快就通过了&#xff0c;但是文心一言至今杳无音讯。文心一言通过审之后&#xff0c;很快将AI BOT的AI能力接入了文心…

从头学前端-CSS3提升-续

CSS3 2D转换 关键字&#xff1a;transform 移动&#xff1a;沿着x,y轴移动&#xff0c;不会影响盒子的位置&#xff0c;对行内元素没有效果 div {width: 100px;height: 100px;background-color: rebeccapurple;transform: translate(100px,100px);transform: translateX(100p…