斐波那契查找(FibonacciSearch)
来源:互联网 发布:大学生如何开淘宝网店 编辑:程序博客网 时间:2024/06/15 15:16
说明
二分搜寻法每次搜寻时,都会将搜寻区间分为一半,所以其搜寻时间为O(log(2)n),log(2)表示以2为底的log值,这边要介绍的费氏搜寻,其利用费氏数列作为间隔来搜寻下一个数,所以区间收敛的速度更快,搜寻时间为O(logn)。
方法
该方法稍有些繁琐,对照代码更容易理解。费氏搜寻使用费氏数列来决定下一个数的搜寻位置,所以必须先制作费氏数列,这在之前有提过;费氏搜寻会先透过公式计算求出第一个要搜寻数的位置,以及其代表的费氏数,以搜寻对象10个数字来说,第一个费氏数经计算后一定是F5,而第一个要搜寻的位置有两个可能,例如若在下面的数列搜寻的话(为了计算方便,通常会将索引0订作无限小的数,而数列由索引1开始):
-∞ 1 3 5 7 9 13 15 17 19 20
如果要搜寻5的话,则由索引F5(F5表示第五个费式数作为索引,也就是5)开始搜寻,接下来如果数列中的数大于指定搜寻值时,就往左找,小于时就向右,每次找的间隔是F4(第四个费式数作为索引,也就是3)、F3(第三个费式数作为索引,也就是2)、F2(第二个费式数作为索引,也就是1)来寻找,当费氏数为0时还没找到,就表示寻找失败,如下所示:
如果要搜寻19,由于第一个搜寻值索引F5处的值小于19,所以此时必须对齐数列右方,也就是将第一个搜寻值的索引改为F5+2 = 7,然后如同上述的方式进行搜寻,如下所示:
至于第一个搜寻值是如何找到的?我们可以由以下这个公式来求得,其中n为搜寻对象的个数,Fy为第y个费式数,必须大于等于n,若算出x值,则使用Fx作为第一个搜寻索引,也就是第x个费式数:
以10个搜寻对象来说:
取Fy = 8, m = 2,所以可以对照费氏数列得到8是第六个费式数,所以y=6,所以x得5,也就是使用第五个费式数的值(也就是5)作为索引开始搜寻。
如果数列在索引5处的值大于指定的搜寻值,则第一个搜寻位置就是索引5的位置,如果小于指定的搜寻值,则第一个搜寻位置必须加上m,也就是F5 + m = 5 + 2 = 7,也就是索引7的位置,其实加上m的原因,是为了要让下一个搜寻值刚好是数列的最后一个位置。
费氏搜寻看来难懂,但只要掌握Fy + m = n这个公式,自己找几个实例算一次,很容易就可以理解;费氏搜寻除了收敛快速之外,由于其本身只会使用到加法与减法,在运算上也可以加快。
C代码
C代码
#include <stdio.h> #include <stdlib.h> #include <time.h> #include <stdio.h> #include <stdlib.h> #include <time.h> #define INT_MIN -9999void createFibonacci(int[], int); int findY(int[], int); int fibonacciSearch(int[], int, int); int main(void) { int number[] = {1, 2, 3, 5, 6, 8, 9, 10, 11};int length = sizeof(number) / sizeof(int);printf("数列:"); int i;for(i = 0; i < length; i++) printf("%d ", number[i]); printf("\n输入寻找对象:"); int find;scanf("%d", &find); if((i = fibonacciSearch(number, length, find)) >= 0) printf("找到数字于索引:%d ", i); else printf("\n找不到指定数"); printf("\n"); return 0; } //建立斐波那契数列void createFibonacci(int Fib[], int length) { Fib[0] = 0; Fib[1] = 1; int i;for(i = 2; i < length; i++) Fib[i] = Fib[i-1] + Fib[i-2]; } //找Y值 int findY(int Fib[], int n) { int i = 0; while(Fib[i] <= n) i++; i--; return i; } //斐波那契查找int fibonacciSearch(int number[], int length, int find) { int* Fib = (int*)(malloc(length * sizeof(int)));int f;for(f = 0; f < length; f++) {Fib[f] = INT_MIN;}createFibonacci(Fib, length); int y = findY(Fib, length + 1); int m = length - Fib[y]; int x = y - 1; int i = x; if(number[i] < find) i += m; int result = -1;while(Fib[x] > 0) { if(number[i] < find) i += Fib[--x]; else if(number[i] > find) i -= Fib[--x]; else {result = i;break;}} free(Fib);return result; }
转载自:http://caterpillar.onlyfun.net/Gossip/AlgorithmGossip/FibonacciSearch.htm
- 斐波那契查找(FibonacciSearch)
- 查找-斐波那契查找
- 算法--查找--斐波那契查找
- 斐波那契查找
- 斐波那契查找
- 斐波那契查找
- 斐波那契查找
- 斐波那契查找
- 斐波那契查找
- 斐波那契查找
- 斐波那契查找
- 斐波那契查找
- 斐波那契查找
- 斐波那契查找
- 斐波那契查找
- 斐波那契查找
- 斐波那契查找
- 二分查找,插值查找,斐波那契查找
- 码间干扰
- EAS WebService访问地址
- HDFS的文件操作流(2)——读操作
- MFC中框架文档视图结构的命令路由处理
- 输入输出流 第一篇
- 斐波那契查找(FibonacciSearch)
- 实际用户ID,有效用户ID及设置用户ID
- 2011 移动互联大会杂谈:天网正在到来,T800 不远了
- 输入输出流 第二篇
- 集合与列表2
- EL表达式
- 用Session来完成用户登录,防止表单重复提交。
- postgresql , postgis 安装
- EAS导入license异常问题