關於Fibonacci算法及Lucas算法說明

Fibonacci查找算法是基於有序序列的,在二分法查找基礎上做出的改進,屬於黃金比例搜索算法。Fibonacci數列的每一項與其後一項之比都接近於0.618,而且越往後比值越接近。而Lucas算法則是在Fibonacci算法的基礎上又提出來的一個新的黃金比例算法,與Fibonacci的通項公式

Fib(n) = Fib(n - 1) + Fib(n - 2) (n>=2, Fib(1)=0, Fib(2)=1)

不同的是,Lucas的通項公式爲

Luc(n) = Luc(n - 1) + Luc(n - 2) (n>=2, Luc(1)=1, Luc(2)=3)

即Fibonacci數列前10項爲: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34
而Lucas數列的前10項分別: 1, 3, 4, 7, 11, 18, 29, 47, 76, 123
由上式可以明顯看出,Lucas列的發散程度較Fibonacci數列大。有數據顯示Lucas算法在最優情況下可以比Fibonacci算法更快,當然在最壞情況下也可能更慢。以下爲你實現一下Fibonacci查找及Lucas查找。

/*
 * 這裏採用C++的創建類的方式來實現Fibonacci算法,並將初始化時計算得出的Fibonacci數列值保存起來
 * 便於下次直接使用。同時,運用成員函數Prev()和Next()也很方便的獲取得到相鄰的Fibonacci數列值
 */
class Fibon
{
public:
    Fibon( int length)                      
    {                                      // 根據待查找序列的長度來確定當前的Fibonacci數列值 
        prev = 1;                          // 即構造成功後,curr的值最大化的接近length,可能大於或小於等於
        curr = 0;
        while( curr < length)
            next();
    }
    int GetCurr() const { return curr;}    // 獲取當前指向的Fibonacci數列值
    int Prev()                             // 不論是前移還是後移,prev和curr都要同步倒退
    { 
        prev = curr - prev;                // 將上一位置的Fibonacci數列值後退一位
        curr = curr - prev;                // 將當前位置的Fibonacci數列值後退一位
        return curr;
    }
    int Next()                             // 理同Prev函數
    {
        curr = curr + prev;
        prev = curr - prev;
        return curr;
    }
private:
    int prev;         // 表示當前位置的前一個Fibonacci數列值
    int curr;         // 表示當前位置的Fibonacci數列值
};

以下是Fibonacci查找算法的實現,在此做出聲明:

本Fibonacci算法不要求待查找序列的長度爲某個Fibonacci數列值減1,即長度不受限制
本算法基於待查找序列長度找到小於或等於該序列長度的Fibonacci數列值,並使該數列值做爲[low, mid)的區間長度
即(mid, high]的區間長度並不一定是Fibonacci數列值

static int FiboSearch( int *array, int input, int low, int high)
{
    Fibon fibon( high - low);                        // 根據待查找序列長度計算出相應的Fibonacci數列值
    while( low < high)
    {
        while( high - low < fibon.GetCurr())         // 每進入一個新的區間,[low, mid)或者(mid, high]都要重新
            fibon.Prev();                            // 計算一個新的Fibonacci數列值來做爲mid 
        int mid = low + fibon.GetCurr() - 1;

        if( input < array[mi])
            high = mid;
        else if( array[mi] < input)
            low = mid + 1;
        else
            return mid;
    }
    return -1;                                       // 如果查找沒有結果,統一返回-1
}

以上爲Fibonacci查找的具體實現步驟,而Lucas其實理同Fibonacci算法,只需要將Fibonacci的類的構造函數中

prev = 1;
curr = 0;

改爲

prev = 2;
curr = 1;

即可。其實是因爲curr要能表示第一位,所以Fibonacci類中構造函數初始化prev爲1,因爲prev+curr就可以等於curr的下一個數,即1。
Lucas算法的初始化函數理同。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章