《算法》第一章——僅用加減實現的二分查找

僅用加減實現的二分查找算法叫斐波那契查找。

算法的大致思路參考:http://blog.csdn.net/zsw12013/article/details/50003505——斐波那契查找(黃金分割法查找)(僅使用加減實現的二分查找)


代碼:

#include <iostream>
#include <algorithm>
using namespace std;

class FibonacciSearch
{
public:
    FibonacciSearch(int a[],int size):arrsize(size),fibo_last_index(0)
    {
        pf = new int[arrsize];//分配足夠大的空間
        pa = new int[arrsize * 2];

        for(int i = 0;i < arrsize;++i)
        {
            pa[i] = a[i];
        }
    }
    ~FibonacciSearch()
    {
        delete pf;
        delete pa;
    }

    int search(int key)
    {
        generate_fibonacci();

        int i = arrsize;
        while(pf[fibo_last_index] > i)
        {
            pa[i] = pa[arrsize - 1];//用最後一個元素填充
            ++i;
        }
        sort(pa,pa + i);//先排序

        int start = 0;
        int end = i;//將end初始化爲數組最後一個元素的索引+1,即第一個非數組元素的索引(和stl迭代器末尾位置一樣)
        int split_point;
        int index = fibo_last_index;
        while(end - start > 1)
        {
            split_point = end - pf[index - 2];
            if(key == pa[split_point])
            {
                return split_point;
            }
            else if(key < pa[split_point])
            {
                end = split_point;
                index = index - 1;
            }
            else
            {
                start = split_point;
                index = index - 2;
            }
        }
        if(end  - start == 1)//長度爲1的情形沒有辦法再進行分割所以需要單獨討論
        {
            if(key == pa[start])
                return start;//這裏必須return start而不能是end,因爲這裏和我設置我end的初值是對應的。end所指的值要麼不在比較範圍內,要麼已經在上一輪裏比較過了。
        }
        return -1;
    }

private:
    void generate_fibonacci()
    {
        pf[0] = pf[1] = 1;
        pf[2] =2;
        int i;
        for(i = 2;pf[i] < arrsize;++i)//找到fibonacii數列中第一個不小於arrsize的數的索引
        {
            pf[i+1] = pf[i] + pf[i-1];
        }
        fibo_last_index = i;
    }
private:
    int arrsize;//需要排序的數組大小
    int fibo_last_index;//會用到的fibonacii數列最後一個元素的索引
    int *pf;//用於存放生成的fibonacii數列
    int *pa;//輔助數組,用於存放填充後的被排序數組
};

int main()
{
    int a[5] = {1,3,4,6,8};
    FibonacciSearch fs(a,sizeof(a)/sizeof(a[0]));
    cout << fs.search(4) << endl;//如果給的原始數組不是遞增有序的,那麼返回的索引是和排序後的一致的。
}



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