《演算法導論》之hash表

2021-06-29 15:15:58 字數 1354 閱讀 3731

hash表原理不難,難在如何選擇表的大小以及hash函式,這個涉及到很多數學的東西,這裡就先不詳述了,而是先整理下基本概念和一些結論。

hash就是通過函式,將大範圍的key值對映到小範圍的hash表中,相比起直接對映來說更加節省空間。而這種方法的乙個問題就是會出現「碰撞」,即有多個值會對映到同乙個**項(槽)中。

所以hash主要問題有兩個:1.如何將key值盡量隨機(少碰撞地)對映到hash表中,即如何設計hash函式。2.如果發生碰撞,如何解決。

一. 如何設計hash函式:三種方法——除法雜湊、乘法雜湊、全域雜湊。當然這些前提是key為自然數。如果key不是自然數,應設法轉換為自然數。

1. 除法雜湊

雜湊函式:h(k) = k mod m,其中k為key值,m為槽數。

注意事項:其中一種情況是,m應為與2的整數冪不太接近的質數。否則等於取k的低位,沒有隨機效果。

2. 乘法雜湊

雜湊函式:h(k) = floor(m(ka mod 1)),其中0注意事項:優點是對m沒特別要求,通常是2的某個冪次,因為適合計算機運算。對a沒特別要求,有研究認為最好的a是(sqrt(5)-1)/2 = 0.618....。

3. 全域雜湊

雜湊函式:在計算時從一組hash函式中隨機的選擇乙個函式

雜湊函式樣例:ha,b(k) = ((ak + b)mod p) mod m,其中p為大於最大k的質數,0注意事項:對於m沒有特別要求。雜湊函式簇就是所有符合條件的a與b不同組合得到的函式。

二. 如何解決碰撞。解決碰撞有兩大類方法:鏈結法和開放定址法。

1. 鏈結法。主要特點是碰撞通過在槽中維護鍊錶來解決碰撞,這樣發生碰撞的key都可以儲存在同一槽中,通過遍歷鍊錶來查詢key。

2. 開放定址。不維護鍊錶,而是通過一些偏移的方法將所有key對映在槽中。有三種方法:線性探查、二次探查、雙重探查。

a. 線性探查

雜湊函式:h(k,i) = (h'(k) + i) mod m, i=0,1,...,其中i為探查次數

注意事項:這個意思就是,先用普通的雜湊函式計算出乙個值,如果發生碰撞,就加上探查次數再取餘,直到成功找到空槽。就是依次往後找到空槽。

b. 二次探查

雜湊函式:h(k,i) = (h'(k) + c1*i + c2*i^2) mod m,其中c2!=0。

注意事項:效果比線性探查好,c1、c2和m要受到限制。

c. 雙重雜湊

雜湊函式:h(k,i) = (h1(k) + i*h2(k)) mod m。

注意事項:開放定址最好的方法。為了能查詢整個表,h2(k)要與m互質。

另外還有完全雜湊的方法,即最壞情況下記憶體訪問為o(1)。實現方法可以用二級雜湊,雜湊表的每個槽都是乙個雜湊,每級都使用全域雜湊。當然這要求key是靜態的。

hash表 hash演算法

概念 雜湊表 hash table。也叫雜湊表 是依據關鍵碼值 key value 而直接進行訪問的 資料結構。也就是說,它通過把關鍵碼值對映到表中乙個位置來訪問記錄,以加快查詢的速度。這個對映函式叫做雜湊函式,存放記錄的陣列叫做雜湊表。給定表m,存在函式f key 對隨意給定的keyword值ke...

演算法之個人總結 Hash表之簡單應用

http chelu01.blog.163.com blog static 9417780520102512312223 本人感覺相當不錯的hash 前段時間看了個微軟編寫的c庫函式,在這個庫函式裡學到乙個自我感覺相當牛比的小演算法,說白了是hash表的應用。大家都知道,hash表最主要是用來實 現...

《演算法導論》雜湊表

雜湊表 hash table 是實現字典操作 查詢 插入 刪除 的有效資料結構,具有很高的查詢效率。一定情況下查詢元素的期望時間是o 1 優於鍊錶 o n 和直接定址的陣列 查詢也是o 1 相當。但當實際儲存的關鍵字數比可能的關鍵字總數小的時候,雜湊錶比陣列有效。一些記號 直接定址,關鍵字k存放在第...