當我們從字典中查詢 「algorithm」 這個單詞的時候,我們肯定不會傻傻地像二分查詢一樣首先從中間開始。相反,我們會從首字母為 a 的地方開始查詢,然後根據第二個字母在字母表中的位置,找到相應的位置再繼續查詢,這樣重複這個過程,直到我們查詢到這個單詞。
接下來我們就來介紹一下類似於上述過程的插值查詢。
插值查詢(interpolation search)實際上是二分查詢的改良版。假設有這樣乙個陣列
均勻分布。如果要查詢元素
這裡,我們用乙個公式來表示每次查詢的期望索引值:
其中,l
和r
分別代表陣列的第乙個和最後乙個索引,key
代表待查詢的元素。
跟二分查詢一樣,如果一次查詢失敗,陣列的長度就相應地減小,再代入上面的公式繼續查詢,直到查詢成功或失敗。
def formula(l, r, key, array):
p = (key - array[l]) / (array[r] - array[l])
n = r - l
idx = int(n * p)
return idx
def interpolation_search(array, key):
l = 0; r = len(array) - 1
while l <= r:
m = l + formula(l, r, key, array)
if array[m] == key:
return m # 查詢成功
elif array[m] < key:
l = m + 1 # 查詢右側的陣列
else:
r = m - 1 # 查詢左側的陣列
return -1 # 查詢失敗
插值查詢的平均複雜度為
**給出了詳細的證明過程,感興趣的同學可以自己去看看,這裡我們就不再討論了。
要是陣列不是均勻分布的,插值查詢的複雜度會退化到線性的複雜度
因此,插值查詢的高效性只針對均勻分布的陣列,而對於分布不均勻的陣列,插值查詢便不再適用了。
→本節全部**←
← 二分查詢與二叉樹 | 演算法與複雜度zhuanlan.zhihu.com
→ 歸併排序 | 演算法與複雜度zhuanlan.zhihu.com
平均查詢長度詳解
分塊查詢是折半查詢和順序查詢的一種改進方法,折半查詢雖然具有很好的效能,但其前提條件時線性表順序儲存而且按照關鍵碼排序,這一前提條件在結點樹很大且表元素動態變化時是難以滿足的。而順序查詢可以解決表元素動態變化的要求,但查詢效率很低。如果既要保持對線性表的查詢具有較快的速度,又要能夠滿足表元素動態變化...
雜湊表查詢 的 平均長度
將關鍵字序列 7 8 30 11 18 9 14 雜湊儲存到雜湊表中。雜湊表的儲存空間是乙個下標從0開始的一維陣列。雜湊函式為 h key key 3 mod 7,處理衝突採用線性探測再雜湊法,要求裝填 載 因子為0.7。1 請畫出所構造的雜湊表 2 分別計算等概率情況下查詢成功和查詢不成功的平均查...
建立雜湊表 查詢及計算平均查詢長度
include include includetypedef struct 元素型別定義 datatype typedef struct 雜湊表型別定義 hashtable void createhashtable hashtable h,int m,int p,int hash,int n int...