《算法》第一章——仅用加减实现的二分查找

仅用加减实现的二分查找算法叫斐波那契查找。

算法的大致思路参考: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;//如果给的原始数组不是递增有序的,那么返回的索引是和排序后的一致的。
}



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