經過構造性能良好的哈希函數,能夠減小衝突,但通常不可能徹底避免衝突,所以解決衝突是哈希法的另外一個關鍵問題。建立哈希表和查找哈希表都會遇到衝突,兩種狀況下解決衝突的方法應該一致。下面以建立哈希表爲例,說明解決衝突的方法。經常使用的解決衝突方法有如下四種:數組
這種方法也稱再散列法,其基本思想是:當關鍵字key的哈希地址p=H(key)出現衝突時,以p爲基礎,產生另外一個哈希地址p1,若是p1仍然衝突,再以p爲基礎,產生另外一個哈希地址p2,…,直到找出一個不衝突的哈希地址pi ,將相應元素存入其中。這種方法有一個通用的再散列函數形式:ide
Hi=(H(key)+di)% m i=1,2,…,n函數
其中H(key)爲哈希函數,m 爲表長,di稱爲增量序列。增量序列的取值方式不一樣,相應的再散列方式也不一樣。主要有如下三種:性能
dii=1,2,3,…,m-1spa
這種方法的特色是:衝突發生時,順序查看錶中下一單元,直到找出一個空單元或查遍全表。指針
di=12,-12,22,-22,…,k2,-k2 ( k<=m/2 )orm
這種方法的特色是:衝突發生時,在表的左右進行跳躍式探測,比較靈活。xml
di=僞隨機數序列。內存
具體實現時,應創建一個僞隨機數發生器,(如i=(i+p) % m),並給定一個隨機數作起點。hash
例如,已知哈希表長度m=11,哈希函數爲:H(key)= key % 11,則H(47)=3,H(26)=4,H(60)=5,假設下一個關鍵字爲69,則H(69)=3,與47衝突。
若是用線性探測再散列處理衝突,下一個哈希地址爲H1=(3 + 1)% 11 = 4,仍然衝突,再找下一個哈希地址爲H2=(3 + 2)% 11 = 5,仍是衝突,繼續找下一個哈希地址爲H3=(3 + 3)% 11 = 6,此時再也不衝突,將69填入5號單元。
若是用二次探測再散列處理衝突,下一個哈希地址爲H1=(3 + 12)% 11 = 4,仍然衝突,再找下一個哈希地址爲H2=(3 - 12)% 11 = 2,此時再也不衝突,將69填入2號單元。
若是用僞隨機探測再散列處理衝突,且僞隨機數序列爲:2,5,9,……..,則下一個哈希地址爲H1=(3 + 2)% 11 = 5,仍然衝突,再找下一個哈希地址爲H2=(3 + 5)% 11 = 8,此時再也不衝突,將69填入8號單元。
這種方法是同時構造多個不一樣的哈希函數:
Hi=RH1(key) i=1,2,…,k
當哈希地址Hi=RH1(key)發生衝突時,再計算Hi=RH2(key)……,直到衝突再也不產生。這種方法不易產生彙集,但增長了計算時間。
這種方法的基本思想是將全部哈希地址爲i的元素構成一個稱爲同義詞鏈的單鏈表,並將單鏈表的頭指針存在哈希表的第i個單元中,於是查找、插入和刪除主要在同義詞鏈中進行。鏈地址法適用於常常進行插入和刪除的狀況。
這種方法的基本思想是:將哈希表分爲基本表和溢出表兩部分,凡是和基本表發生衝突的元素,一概填入溢出表。