僅用加減實現的二分查找算法叫斐波那契查找。
算法的大致思路參考: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;//如果給的原始數組不是遞增有序的,那麼返回的索引是和排序後的一致的。
}