费氏查找(Fibonacci Searching): 类似于折半查找(Binary Searching),只不过折半查找是运用除法运算减少查找范围,而费氏查找则采用了加减运算,所以理论上费氏查找的效率优于折半查找。
必须明确的几个概念:
由n <= F(a) –1 求出 a; F(a)为费氏数列, n为中的结点
由a确定最初的几个值:
root = F(a - 1);
distance_1 = F(a - 2);
distance_2 = F(a - 3);
(1) 如果keyValue < data[root -1], 则表示在keyValue出现在data[root-1]之前
这时:
root = root - distance_2;
temp = distance_1;
distance_2 = temp – distance_1;
(2) 如果keyValue > data[root -1], 则表示在keyValue出现在data[root-1]之后
这时:
root = root + distance_2;
distance_1 = diatance_1 – distance_2;
distance_2 = distance_2 – distance_1;
具体概念见 下载资源:基于费氏树的费氏查找思想的探索与实现
或者:http://download.csdn.net/detail/johnnyhu90/6030293
下面是简单的费氏查找的操作代码:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
/***********************************************************/
// 程序名称:FibonacciSearch.cpp // 程序目的:设计一个费氏查找的程序 // 程序来源:数据结构与算法分析(C语言版) P-287 // 日期: 2013-8-29 9:18:07 JohnnyHu改进 /***********************************************************/ #include <stdio.h> #include <stdlib.h> #define MAX 20 #define NotFound - 1 typedef int ElementType; ElementType data[MAX] = { 12, 14, 19, 22, 25, 32, 39, 40, 45, 47, 48, 53, 54, 59, 60, 68, 69, 68, 70, 77 }; // 数据数组 int Fib( int n); int FibonacciSearch( const ElementType data[], ElementType keyValue, int n); int main( void) { int fibIndex = 1; while (Fib(fibIndex) < MAX + 1) fibIndex++; int keyValue; printf( "请输入您要查找的(int)值,输入0退出: "); while(scanf( "%d", &keyValue)) { if ( 0 == keyValue) break; int index = FibonacciSearch(data, keyValue, fibIndex); if (NotFound != index) printf( "您要查找的值是: data[%d] = %d \n", index, data[index]); else printf( "没找到!\n"); printf( "请输入您要查找的(int)值,输入0退出: "); } return 0; } /************************************************************************/ // 递归求费氏级数(此函数n>30后效率会很低) /************************************************************************/ int Fib( int n) { if (n <= 1) return 1; else return Fib(n - 1) + Fib(n - 2); } /************************************************************************/ // 费氏查找 /************************************************************************/ int FibonacciSearch( const ElementType data[], ElementType keyValue, int n) { int root; // 树根 int distance_1, distance_2; // 节点差值 int temp = 0; root = Fib(n - 1); distance_1 = Fib(n - 2); distance_2 = Fib(n - 3); do { if (keyValue < data[root - 1]) { // 查找前半段 root = root - distance_2; temp = distance_1; distance_1 = distance_2; distance_2 = temp - distance_2; } else if (keyValue > data[root - 1]) { // 查找后半段 root = root + distance_2; distance_1 = distance_1 - distance_2; distance_2 = distance_2 - distance_1; } else { // 查找到数据 return root - 1; // 返回索引 } } while (distance_2 >= 0); return NotFound; } |