费氏搜寻法简介

费氏搜寻法,就是利用斐波那契数列从有序数列中搜寻特定元素的一种搜索算法。

二分搜寻法每次搜寻时,都会将搜寻区间分为一半,所以其搜寻时间为O(log(2)n),log(2)表示以2为底的log值,这边要介绍的费氏搜寻,其利用费氏数列作为间隔来搜寻下一个数,所以区间收敛的速度更快,搜寻时间为O(logn)。

费氏搜寻法算法分析

费氏搜寻使用费氏数列来决定下一个数的搜寻位置,所以必须先制作费氏数列,这在之前有提过;费氏搜寻会先透过公式计算求出第一个要搜寻数的位置,以及其代 表的费氏数,以搜寻对象10个数字来说,第一个费氏数经计算后一定是F5,而第一个要搜寻的位置有两个可能,例如若在下面的数列搜寻的话(为了计算方便, 通常会将索引0订作无限小的数,而数列由索引1开始):

-infin; 1 3 5 7 9 13 15 17 19 20

如果要搜寻5的话,则由索引F5 = 5开始搜寻,接下来如果数列中的数小于指定搜寻值时,就往左找,大于时就向右,每次找的间隔是F4、F3、F2来寻找,当费氏数为0时还没找到,就表示寻找失败,如下所示:

由于第一个搜寻值索引F5 = 5处的值小于19,所以此时必须对齐数列右方,也就是将第一个搜寻值的索引改为F5+2 = 7,然后如同上述的方式进行搜寻,如下所示:

至于第一个搜寻值是如何找到的?我们可以由以下这个公式来求得,其中n为搜寻对象的个数:

Fx + m = n

Fx <= n

也就是说Fx必须找到不大于n的费氏数,以10个搜寻对象来说:

Fx + m = 10

取Fx = 8, m = 2,所以我们可以对照费氏数列得x = 6,然而第一个数的可能位置之一并不是F6,而是第x-1的费氏数,也就是F5 = 5。

如果数列number在索引5处的值小于指定的搜寻值,则第一个搜寻位置就是索引5的位置,如果大于指定的搜寻值,则第一个搜寻位置必须加上m,也就是F5 + m = 5 + 2 = 7,也就是索引7的位置,其实加上m的原因,是为了要让下一个搜寻值刚好是数列的最后一个位置。

费氏搜寻看来难懂,但只要掌握Fx + m = n这个公式,自己找几个实例算一次,很容易就可以理解;费氏搜寻除了收敛快速之外,由于其本身只会使用到加法与减法,在运算上也可以加快。

费氏搜寻法的实现

#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 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 = 6;                      //要寻找的对象
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的初值也是确定的。PS:这就是公式的力量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);      // 对右边进行递回}
}

转载于:https://www.cnblogs.com/riasky/p/3508807.html

费氏搜寻法之算法分析与实现相关推荐

  1. 费氏(Fibonacci)数列、最大公约数,最小公倍数

    费式数列 说明 Fibonacci为1200年代的欧洲数学家,在他的着作中曾经提到:「若有一只免子每个月生一只小免子,一个月后小免子也开始生产.起初只有一只免子,一个月后就有两只免子,二个月后有三只免 ...

  2. python筛选法求素数讲解_埃氏筛选法求素数 Python

    代码如下 def _odd_iter(): # 构建奇数序列 从3开始 n = 1 while True: n = n + 2 yield n def _not_divisible(n): retur ...

  3. C++经典算法题-循序搜寻法(使用卫兵)

    42.Algorithm Gossip: 循序搜寻法(使用卫兵) 说明 搜寻的目的,是在「已排序的资料」中寻找指定的资料,而当中循序搜寻是最基本的搜寻法, 只要从资料开头寻找到最后,看看是否找到资料即 ...

  4. 【循环搜寻法(使用卫兵)】

    /* 循环搜寻法(使用卫兵) 说明: 搜寻的目的,是在「已排序的资料」中寻找指定的资料,而当中循序搜寻是最基本的搜寻法,只要从资料开头寻找到最后,看看是 否找到资料即可. 解法: 初学者看到循序搜寻, ...

  5. 索氏提取器使用注意_索氏提取法注意事项

    注意事项 脂肪广泛存在于许多植物的种子和果实中,测定脂肪的含量,可以作为鉴别其品质优劣的一个指标.脂肪含量的测定有很多方法,如抽提法.酸水解法.比重法.折射法.电测和核磁共振法等.目前国内外普遍采用抽 ...

  6. CC00033.bigdatajava——|Java方法封装.V15|——|Java.v15|费氏数列.v01|递归实现|

    一.费氏数列的递归实现 ### --- 案例题目~~~ --> 编程实现费式数列中第n项的数值并返回. ~~~ --> 费式数列:1 1 2 3 5 8 13 21 -- 二.递归分析 三 ...

  7. CC00034.bigdatajava——|Java方法封装.V16|——|Java.v16|费氏数列.v02|递推实现|

    一.费氏数列的递推实现 ### --- 案例题目~~~ --> 编程实现费式数列中第n项的数值并返回. ~~~ --> 费式数列:1 1 2 3 5 8 13 21 -- 二.递推实现原理 ...

  8. C实现 费氏查找算法

    问题引入 费氏数列即斐波那契数列. 斐波那契数列,又称黄金分割数列,数列形式为:0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,377,610,98 ...

  9. Procrustes Analysis普氏分析法

    选取N幅同类目标物体的二维图像,并用上一篇博文的方法标注轮廓点,这样就得到训练样本集: 由于图像中目标物体的形状和位置存在较大偏差,因此所得到的数据并不具有仿射不变性,需要对其进行归一化处理.这里采用 ...

最新文章

  1. 超级细分插件_草图大师必装插件
  2. 43 JavaScript中的浅拷贝与深拷贝
  3. python怎么装饰_如何理解python装饰器
  4. iOS 使用Touch ID 校验[新增 iOS9 三种错误]
  5. 为什么转换不了html,特殊字符不会转换为html实体(html_entity_decode不工作)
  6. 计算机网址登录教程,melogincn电脑登录教程
  7. java容器相关问题
  8. php imagick手册,PHP中使用Imagick实现各种图片效果实例
  9. bind_param 类怎么写_情感类自媒体怎么写?你不知道的情感类文章4大禁忌!
  10. 文本属性之装饰文本(CSS、HTML)
  11. ObjC解码汉字网页乱码问题
  12. 设置linux服务器下开放端口
  13. python画太阳花代码
  14. 2022-2027年中国非人寿保险市场竞争态势及行业投资前景预测报告
  15. 计算机主机三短一长,电脑主机出现三短一长响声怎么办
  16. Windows8/Silverlight/WPF/WP7周学习导读(11月12日-11月18日)
  17. 一口气讲完设计模式(单例模式、工厂模式、原型模式、建造者模式、适配器、桥梁模式)
  18. 如何查看软件是32位还是64位
  19. java数字音频最强教程之音频的王者之路(音频发烧友篇)
  20. python 安装CV2

热门文章

  1. ASP.NET MVC学习之路由篇(2)
  2. 删除系统Win7系统盘越来越小,系统盘清理技巧
  3. 在Source Insight中看Python代码
  4. 25.计算机和计算器的区别
  5. windows下python3关于机器学习的环境配置,Anaconda的安装和使用方法以及安装后无法打开的解决方法
  6. base64的c语言实现方法
  7. 利用oracle执行系统命令,利用oracle存储过程执行操作系统命令(转)
  8. android自动创建桌面,Android应用启动后自动创建桌面快捷方式的实现方法
  9. java跳槽原因_跳槽求职必看:Java程序猿面试失败的5大原因!
  10. java---编写一个方法,返回一个int型的二维数组,数组中的元素通过解析字符串参数获得。