仅用加减实现的二分查找算法叫斐波那契查找。
算法的大致思路参考: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;//如果给的原始数组不是递增有序的,那么返回的索引是和排序后的一致的。
}