zoukankan      html  css  js  c++  java
  • 费氏搜索浅谈

    说明:

    二分搜尋法每次搜尋時,都會將搜尋區間分為一半,所以其搜尋時間為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的話,則由索引F5F5表示第五個費式數作為索引,也就是5)開始搜尋,接下來如果數列中的數大於指定搜尋值時,就往左找,小於時就向右,每次找的間隔是F4(第四個費式數作為索引,也就是3)、F3(第三個費式數作為索引,也就是2)、F2(第二個費式數作為索引,也就是1)
    來尋找,當費氏數為0時還沒找到,就表示尋找失敗,如下所示:
    費式搜尋

    如果要搜尋19,由於第一個搜尋值索引F5處的值小於19,所以此時必須對齊數列右方,也就是將第一個搜尋值的索引改為F5+2 = 7,然後如同上述的方式進行搜尋,如下所示:
    費式搜尋
    至於第一個搜尋值是如何找到的?我們可以由以下這個公式來求得,其中n為搜尋對象的個數,Fy為第y個費式數,必須大於等於n,若算出x值,則使用Fx作為第一個搜尋索引,也就是第x個費式數:
    Fy + m = n
    Fy
    >= n + 1
    x = y - 1

    以10個搜尋對象來說:
    Fy + m = 10

    Fy = 8, m = 2,所以可以對照費氏數列得到8是第六個費式數,所以y=6,所以x得5,也就是使用第五個費式數的值(也就是5)作為索引開始搜尋。

    如果數列在索引5處的值大於指定的搜尋值,則第一個搜尋位置就是索引5的位置,如果小於指定的搜尋值,則第一個搜尋位置必須加上m,也就是F5 + m = 5 + 2 = 7,也就是索引7的位置,其實加上m的原因,是為了要讓下一個搜尋值剛好是數列的最後一個位置。

    費氏搜尋看來難懂,但只要掌握Fy + m = n這個公式,自己找幾個實例算一次,很容易就可以理解;費氏搜尋除了收斂快速之外,由於其本身只會使用到加法與減法,在運算上也可以加快。


    //建立费氏数列
    void createfib()
    {
          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 find)
    {
          int i = 0;
          while(Fib[i] <= n)
          i++;
          return --i;
    }
    //费氏搜寻
    int fibsearch(int number[],int find)
    {
            int i ,x,m;
            createfib();
            x = findx(MAX+1,find);
            m = MAX - Fib[x];
            printf("\nx=%d,m = %d,Fib[x] = %d\n\n",x,m,Fib[x]);
            x--;
           i = x;

    //费氏搜索关键代码
          if(number[i] < find)
                 i += m;
          while(Fib[x] > 0)
          {
               if(number[i] < find)
                      i +=Fib[--x];
               else
                    if(number[i] > find)
                           i -= Fib[--x];
                   else
                          return i;
     
            }
           return -1;
    }

  • 相关阅读:
    Atitit 经济学常见的流派 古典主义与凯恩斯主义
    Atitit 学习方法 体系化学习方法 Excel 科目,分类,专业 三级分类。。 知识点。。 课程就是每一个知识点的详细化。。 比如经济学 类别 专业 xx概论知识点 3、金
    atiitt it学科体系化 体系树与知识点概念大总结.xlsx
    Atitit 减少财政支出普通人如何蹭政府补贴措施 attilax大总结.docx
    Atitit 信用管理概论 attilax学习心得
    Atitit.月度计划日程表 每月流程表v5
    Atitit 企业6大职能 attilax总结
    Atitit 常见每日流程日程日常工作.docx v8 ver ampm imp 签到 am y 天气情况检查 am y 晨会,每天或者隔天 am 每日计划(项目计划,日计划等。 am
    Atitit 财政赤字解决方案
    Atitit 建设自己的财政体系 attilax总结 1.1. 收入理论 2 1.2. 收入分类 2 1.3. 2 1.4. 非货币收入 2 1.5. 2 1.6. 降低期望 2 1.7.
  • 原文地址:https://www.cnblogs.com/LUO257316/p/3220874.html
Copyright © 2011-2022 走看看