/*斐波那契查詢法,前提是線性表必須有序,時間複雜度是o(logn)*/
#include
const
intmaxsize = 20;
intfibonacci_search(
int*a,
intn,
intkey);
/*用非遞迴法構造乙個斐波那契陣列*/
void
fibonacci(
int*f)
} intmain()
; int
number = fibonacci_search(array,
sizeof
(array)/
sizeof
(int
), 73);
std::cout<<"位置是:array["
<"]\n"
; return
0;
} /*定義斐波那契查詢法*/
intfibonacci_search(
int*a,
intn,
intkey)
for(i=n; i//將a的元素擴充套件到(某斐波那契數 - 1),即f[k]-1
while
(low <= high)
else
if(key > a[mid])
else
} return
-1;
}
首先要明確:如果乙個有序表的元素個數為n,並且n正好是(某個斐波那契數 - 1),即n=f[k]-1時,才能用斐波那契查詢法。 如果有序表的元素個n不等於(某個斐波那契數 - 1),即n≠f[k]-1,這時必須要將有序表的元素擴充套件到大於n的那個斐波那契數 - 1才行,這段**:
[cpp]
view plain
copy
print?
for(int
i = n; i < f[k] - 1; i++)
便是這個作用。
陣列a的長度其實很好估算,比如你定義了有10個元素的有序陣列a[20],n=10,那麼n就位於8和13,即f[6]和f[7]之間,所以k=7,此時陣列a的元素個數要被擴充,為:f[7] - 1 = 12個; 再如你定義了乙個b[20],且b有12個元素,即n=12,那麼很好辦了,n = f[7]-1 = 12, 用不著擴充了; 又或者n=8或9或11,則它一定會被擴充到12; 再如n=13,最後得出n位於13和21,即f[7]和f[8]之間,此時k=8,那麼f[8]-1 = 20,陣列a就要有20個元素了。 所以,n = x(13<=x<=20)時,最後都要被擴充到20;類推,如果n=25呢,則陣列a的元素個數肯定要被擴充到 34 - 1 = 33個(25位於21和34,即f[8]和f[9]之間,此時k=9,f[9]-1 = 33),所以,n = x(21<=x<=33)時,最後都要被擴充到33。也就是說,最後陣列的元素個數一定是(某個斐波那契數 - 1),這就是一開始說的n與f[k]-1的關係。
對於二分查詢,分割是從mid=(low+high)/2開始;而對於斐波那契查詢,分割是從mid = low + f[k-1] - 1開始的; 通過上面知道了,陣列a現在的元素個數為f[k]-1個,即陣列長為f[k]-1,mid把陣列分成了左右兩部分, 左邊的長度為:f[k-1] - 1, 那麼右邊的長度就為(陣列長-左邊的長度-1), 即:(f[k]-1) - (f[k-1] - 1) = f[k] - f[k-1] - 1 = f[k-2] - 1。
斐波那契查詢的核心是:
1)當key=a[mid]時,查詢成功;
2)當keya[mid]時,新的查詢範圍是第mid+1個到第high個,此時範圍個數為f[k-2] - 1個,即陣列右邊的長度,所以要在[f[k - 2] - 1]範圍內查詢。
關於斐波那契查詢, 如果要查詢的記錄在右側,則左側的資料都不用再判斷了,不斷反覆進行下去,對處於當眾的大部分資料,其工作效率要高一些。所以儘管斐波那契查詢的時間複雜度也為o(logn),但就平均效能來說,斐波那契查詢要優於折半查詢。可惜如果是最壞的情況,比如這裡key=1,那麼始終都處於左側在查詢,則查詢效率低於折半查詢。
還有關鍵一點,折半查詢是進行加法與除法運算的(mid=(low+high)/2),插值查詢則進行更複雜的四則運算(mid = low + (high - low) * ((key - a[low]) / (a[high] - a[low]))),而斐波那契查詢只進行最簡單的加減法運算(mid = low + f[k-1] - 1),在海量資料的查詢過程中,這種細微的差別可能會影響最終的效率。
二分查詢與斐波那契查詢
方法一 軸點取中點,逐步遞迴。演算法時間複雜度o log n 主要思路如下圖 不會執行 pre 對於該演算法,我們可以計算出迭代到底部所耗費的時間,計算結果如下圖所示。從圖中可以看出左邊遞迴和右邊遞迴所耗費的步數是不一樣的,那我我們是否可以找到一種演算法讓左邊迭代步數和右邊一致能,這樣能夠減少平均迭...
二分查詢,改進 斐波那契查詢
二分查詢 平均查詢長度o 1.5logn 實現 二分查詢演算法 版本a 在有序向量的區間 lo,hi 內查詢元素e,0 lo hi size typdef int rank template typename t static rank binsearch t s,t const e,rank lo...
二分查詢 插值查詢 斐波那契查詢
在有序表中,取中間記錄作為比較物件,將其與給定值相比較,若其等於給定值,則查詢成功 若其小於給定值,則在中間記錄的右半區繼續查詢 若其大於給定值,則在中間記錄的左半區繼續查詢。不斷重複以上過程,直到查詢成功或無匹配記錄。使用該查詢方法的前提條件在於,線性表中的資料必須有序,且必須採用順序儲存的方式。...