1. 程式人生 > 其它 >hash雜湊衝突常用解決方法

hash雜湊衝突常用解決方法

雜湊衝突常用解決方法

1.基本概念

雜湊演算法:根據設定的雜湊函式H(key)和處理衝突方法將一組關鍵字映象到一個有限的地址區間上的演算法。也稱為雜湊演算法、雜湊演算法。

雜湊表:資料經過雜湊演算法之後得到的集合。這樣關鍵字和資料在集合中的位置存在一定的關係,可以根據這種關係快速查詢。

非雜湊表:與雜湊表相對應,集合中的資料和其存放位置沒任何關聯關係的集合。

由此可見,雜湊演算法是一種特殊的演算法,能將任意資料雜湊後對映到有限的空間上,通常計算機軟體中用作快速查詢或加密使用。

雜湊衝突:由於雜湊演算法被計算的資料是無限的,而計算後的結果範圍有限,因此總會存在不同的資料經過計算後得到的值相同,這就是雜湊衝突。

2.解決雜湊衝突的方法

解決雜湊衝突的方法一般有:開放定址法、鏈地址法(拉鍊法)、再雜湊法、建立公共溢位區等方法。

2.1 開放定址法

開放定址法又叫做開放定址法開地址法,從發生衝突的那個單元起,按照一定的次序,從雜湊表中找到一個空閒的單元。然後把發生衝突的元素存入到該單元的一種方法。開放定址法需要的表長度要大於等於所需要存放的元素。

在開放定址法中根據探查序列生成方式的不同,細分有:線性探查法平方探查法雙雜湊函式探查法偽隨機探查法等。

開放定址法的缺點在於刪除元素的時候不能真的刪除,否則會引起查詢錯誤,只能做一個特殊標記。只到有下個元素插入才能真正刪除該元素。

2.1.1 線性探查法

線行探查法是開放定址法中最簡單的衝突處理方法,它從發生衝突的單元起,依次判斷下一個單元是否為空,當達到最後一個單元時,再從表首依次判斷。直到碰到空閒的單元或者探查完全部單元為止。

2.1.2 平方探查法

平方探查法即是發生衝突時,用發生衝突的單元 d[i], 加上 1²、 2² 等。即 d[i] + 1²,d[i] + 2², d[i] + 3²… 直到找到空閒單元。

在實際操作中,平方探查法不能探查到全部剩餘的單元。不過在實際應用中,能探查到一半單元也就可以了。若探查到一半單元仍找不到一個空閒單元,表明此散列表太滿,應該重新建立。

2.1.3 雙雜湊函式探查法

雙雜湊函式探查法又叫做雙重雜湊探查法

(出自演算法導論),是開發定址法中的最好方法之一,因為它所產生的探查序列具有隨機性。

關於叫法推薦叫雙雜湊函式探查法,因為雙重雜湊探查法的名字有歧義,是使用兩個雜湊函式還是使用一個雜湊函式做兩次雜湊計算呢,沒有那麼直白。

這種方法使用兩個雜湊函式 h1 和 h2。其中 h1 和前面的 h 一樣,以關鍵字為自變數,產生一個 0 至 m-1 之間的數作為雜湊地址;h2 也以關鍵字為自變數,產生一個 1 至 m-1 之間的並和 m 互素的數(即 m 不能被該數整除)作為探查序列的地址增量(即步長)。這樣做是使探查序列能夠分佈在整個 Hash 表。

2.1.4 偽隨機探查法

具體實現時,建立一個偽隨機數發生器來生成探查序列。

例如,假設雜湊表長度 m=11,雜湊函式為:H(key)= key % 11,則 H(47)=3,H(26)=4,H(60)=5,假設下一個關鍵字為 69,則H(69)=3,與 47 衝突。如果用偽隨機探測再雜湊處理衝突,且偽隨機數序列為:2,5,9,…,則下一個雜湊地址為 H1=(3+2)%11=5,仍然衝突,再找下一個雜湊地址為 H2=(3+5)%11=8,此時不再衝突,將 69 填入 8 號單元。

2.1.5 小結

四種不同的開放定址法,根據其探查序列可以看出,線性探查法的步長值固定為 1;平方探查法步長值是探查次數 i 的兩倍減 1;雙雜湊函式探查法,其探查序列的步長值是同一關鍵字的另一雜湊函式的值。對於偽隨機探查法,探查序列是隨機的,所以步長也是隨機的。

2.2 鏈地址法(拉鍊法)

連結地址法的思路是將雜湊值相同的元素構成一個同義詞的單鏈表,並將單鏈表的頭指標存放在雜湊表的第i個單元中,查詢、插入和刪除主要在同義詞連結串列中進行。連結串列法適用於經常進行插入和刪除的情況。

如下一組數字:(32、40、36、53、16、46、71、27、42、24、49、64),雜湊表長度為13,雜湊函式為 H(key)=key%13,則連結串列法結果如下:

0       
1  -> 40 -> 27 -> 53 
2
3  -> 16 -> 42
4
5
6  -> 32 -> 71
7  -> 46
8
9
10 -> 36 -> 49
11 -> 24
12 -> 64

注意:鏈地址法是主流開發語言中 HashMap 衝突的解決辦法,如 Java Go 等。以 Java 為例,JDK1.7 完全採用單鏈表來儲存同義詞,JDK 1.8 則採用了一種混合模式,對於連結串列長度大於8的,會轉換為紅黑樹儲存。

2.3 再雜湊法

就是同時構造多個不同的雜湊函式:

Hi = RHi(key) i= 1,2,3 ... k;

其中 RHi 為不同的雜湊函式。當 H1 = RH1(key) 發生衝突時,再用 H2 = RH2(key) 進行計算,直到衝突不再產生,這種方法不易產生聚集,但是增加了計算時間。

2.4 建立公共溢位區

將雜湊表分為公共表和溢位表,當溢位發生時,將所有溢位資料統一放到溢位區。


參考文獻

[1] 簡書.解決雜湊衝突的常用方法分析
[2] 殷建平,徐雲,王剛等.演算法導論(原書第3版).C11.4開放定址法.P151-155
[3] 張乃孝.演算法與資料結構.C6.5.3碰撞的處理.P189-194
轉自
四種解決方法