9.4 费氏查找

费氏查找(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] = {    1214192225,
                             3239404547,
                             4853545960,
                             6869687077 };  // 数据数组

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;
}
输出结果:



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值