斐波拉契搜索(费氏搜寻法)分析与实现

2024-02-24 18:30

本文主要是介绍斐波拉契搜索(费氏搜寻法)分析与实现,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

要说斐波拉契搜索就必须要先说一下什么 是斐波拉契数列:

斐波拉契数列:
F(1)=1,
F(2)=1,
F(n)=F(n-1)+F(n-2)(n>=3,n∈N*)
就是从第三项开始,每一项都等于前两项的和。

费氏搜寻法简介:
费氏搜寻法,就是利用斐波拉契数列从有序数列中搜寻特定元素的一种搜索算法,它的前提是数列必须要有序。我们熟悉的二分查询,每次搜寻的时候,都会讲区间分为两半,所以其搜寻时间为O(log(2)n),这边要介绍的费氏搜索,其利用费氏数列中的数作为间隔来搜寻下一个数,所以区间收敛的速度会更快,搜索时间为O(logn)。

用一个例子来说明:

查询的数组:num[]
0 0 1 1 1 2 2 2 3 5 6 7 8 8 9
斐波拉契数列:F[]
1 1 2 3 5 8 13 21…

现在假定我们查询的数字是:find=7.
方便计算,我们的num[]和F[]的数组下标都从1开始。
首先,可以知道数组num长度n=15,先找到(尽可能大的)小于等于15的F[x]=13,他的下标x=7,此时还需要一个公式:F[x]+m=n,所以m=15-13=2;
x,m,F[x]在一开始数组长度知道的情况下就可以知道了。

第一次搜索:
不是从x=7,开始查询的,而是x–,i=x=6开始查询的,如果num[6]<7,这时候,i+=m,第二次搜索的时候就从第8个开始。(如果num[6]>7,则i是i-=F[x])
i=6 num[6]=2<7 i+=2

第二次搜索:
第二次搜索就从上一次 得出的i=8开始搜索,这时候,num[8]=2<7,这时候i的变化不再是加减m了,而是加减斐波拉契数列的值(F[x])了。num[i]小于我们要查找的数值,i就加斐波拉契数列的值,反之则减.
i=8 num[8]=2<7 i+=F[–x] 即i+=F[5] i=8+5=13

第三次搜索

i=13 num[13]=8>7 i-=F[–x] 即i-=F[4] i=13-3=10

第四次搜索:
i=10 num[10]=5<7 i+=F[–x] 即i+=F[3] i=10+2=12

第五次搜索:
i=12 num[12]=7 这样就找到我们要查找的数值7,他是索引12.

总结:
费氏搜寻会先透过公式计算求出第一个要搜寻数的位置,F[x]+m=n,计算出F[x],m,x的值,用费氏数列作为间隔来搜寻下一个数,区间收敛的速度更快,同时本身只会用到加减法,在运算上也可以加快。

代码:

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define MAX 15
#define SWAP(x,y) {int t; t = x; x = y; y = t;}void createfib(void);               // 建立费氏数列
int findx(int);                     // 找x值
int fibsearch(int[], int);          // 费氏搜寻
void quicksort(int[], int, int);    // 快速排序int Fib[MAX] = {-999};//主程序(C/OC)int main(void){int number[MAX] = {0};
int i, find;srand(time(NULL));for(i = 1; i <= MAX; i++) {     //产生随机数列number[i] = rand() % 10;
}quicksort(number, 1, MAX);      //快速排序printf("数列:");                //打印排序后的数列
for(i = 1; i <= MAX; i++)printf("%d ", number[i]);
find = 7;                      //要寻找的对象
if((i = fibsearch(number, find)) >= 0)printf("找到数字于索引 %d ", i);
elseprintf("\n找不到指定数");printf("\n"); 
}
//建立费氏数列,总共求得MAX+1个斐波那契数
void createfib(void) {int i;Fib[0] = 0;Fib[1] = 1;for(i = 2; i < MAX; i++)Fib[i] = Fib[i-1] + Fib[i-2];
}//找x值
int findx(int n) {int i = 0;while(Fib[i] <= n)i++;i--;return i;//找到第i个Fib元素小于等于MAX+1
}//费式搜寻
int fibsearch(int number[], int find) {int i, x, m;createfib();                    //创建斐波那契数列x  = findx(MAX+1);              //斐波那契数列中第x个数刚好不大于MAX+1。MAX是确定的,所以比较的起始点是确定的。m = MAX - Fib[x];               //得到一个较小的差值。m的值也是确定的。printf("\nx = %d, m = %d, Fib[x] = %d\n\n",x, m, Fib[x]);x--;i = x;if(number[i] < find)            //i的初值也是确定的。i += m;while(Fib[x] > 0) {             //搜寻,x值不断减小,范围越来越小,搜寻越来越精细if(number[i] < find)        //小于被搜寻的值i += Fib[--x];          //右移搜寻位置else if(number[i] > find)   //大于被搜寻值i -= Fib[--x];          //左移搜寻位置elsereturn i;               //相等,找到}return -1;                      //搜寻步子已经最小,还是没找到,搜寻结束
}//快速排序
void quicksort(int number[], int left, int right) {int i, j, k, s;if(left < right) {s = number[(left+right)/2];i = left - 1;j = right + 1;while(1) {while(number[++i] < s) ;        // 向右找while(number[--j] > s) ;        // 向左找if(i >= j)break;SWAP(number[i], number[j]);}quicksort(number, left, i-1);       // 对左边进行递回quicksort(number, j+1, right);      // 对右边进行递回} 
} 

运行结果:
在这里插入图片描述

这篇关于斐波拉契搜索(费氏搜寻法)分析与实现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/742977

相关文章

Spring Boot 实现 IP 限流的原理、实践与利弊解析

《SpringBoot实现IP限流的原理、实践与利弊解析》在SpringBoot中实现IP限流是一种简单而有效的方式来保障系统的稳定性和可用性,本文给大家介绍SpringBoot实现IP限... 目录一、引言二、IP 限流原理2.1 令牌桶算法2.2 漏桶算法三、使用场景3.1 防止恶意攻击3.2 控制资源

springboot下载接口限速功能实现

《springboot下载接口限速功能实现》通过Redis统计并发数动态调整每个用户带宽,核心逻辑为每秒读取并发送限定数据量,防止单用户占用过多资源,确保整体下载均衡且高效,本文给大家介绍spring... 目录 一、整体目标 二、涉及的主要类/方法✅ 三、核心流程图解(简化) 四、关键代码详解1️⃣ 设置

Nginx 配置跨域的实现及常见问题解决

《Nginx配置跨域的实现及常见问题解决》本文主要介绍了Nginx配置跨域的实现及常见问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来... 目录1. 跨域1.1 同源策略1.2 跨域资源共享(CORS)2. Nginx 配置跨域的场景2.1

Python中提取文件名扩展名的多种方法实现

《Python中提取文件名扩展名的多种方法实现》在Python编程中,经常会遇到需要从文件名中提取扩展名的场景,Python提供了多种方法来实现这一功能,不同方法适用于不同的场景和需求,包括os.pa... 目录技术背景实现步骤方法一:使用os.path.splitext方法二:使用pathlib模块方法三

CSS实现元素撑满剩余空间的五种方法

《CSS实现元素撑满剩余空间的五种方法》在日常开发中,我们经常需要让某个元素占据容器的剩余空间,本文将介绍5种不同的方法来实现这个需求,并分析各种方法的优缺点,感兴趣的朋友一起看看吧... css实现元素撑满剩余空间的5种方法 在日常开发中,我们经常需要让某个元素占据容器的剩余空间。这是一个常见的布局需求

HTML5 getUserMedia API网页录音实现指南示例小结

《HTML5getUserMediaAPI网页录音实现指南示例小结》本教程将指导你如何利用这一API,结合WebAudioAPI,实现网页录音功能,从获取音频流到处理和保存录音,整个过程将逐步... 目录1. html5 getUserMedia API简介1.1 API概念与历史1.2 功能与优势1.3

Java实现删除文件中的指定内容

《Java实现删除文件中的指定内容》在日常开发中,经常需要对文本文件进行批量处理,其中,删除文件中指定内容是最常见的需求之一,下面我们就来看看如何使用java实现删除文件中的指定内容吧... 目录1. 项目背景详细介绍2. 项目需求详细介绍2.1 功能需求2.2 非功能需求3. 相关技术详细介绍3.1 Ja

使用Python和OpenCV库实现实时颜色识别系统

《使用Python和OpenCV库实现实时颜色识别系统》:本文主要介绍使用Python和OpenCV库实现的实时颜色识别系统,这个系统能够通过摄像头捕捉视频流,并在视频中指定区域内识别主要颜色(红... 目录一、引言二、系统概述三、代码解析1. 导入库2. 颜色识别函数3. 主程序循环四、HSV色彩空间详解

PostgreSQL中MVCC 机制的实现

《PostgreSQL中MVCC机制的实现》本文主要介绍了PostgreSQL中MVCC机制的实现,通过多版本数据存储、快照隔离和事务ID管理实现高并发读写,具有一定的参考价值,感兴趣的可以了解一下... 目录一 MVCC 基本原理python1.1 MVCC 核心概念1.2 与传统锁机制对比二 Postg

SpringBoot整合Flowable实现工作流的详细流程

《SpringBoot整合Flowable实现工作流的详细流程》Flowable是一个使用Java编写的轻量级业务流程引擎,Flowable流程引擎可用于部署BPMN2.0流程定义,创建这些流程定义的... 目录1、流程引擎介绍2、创建项目3、画流程图4、开发接口4.1 Java 类梳理4.2 查看流程图4