學習筆記 | 解決Hash衝突的4種辦法

  • 因爲HashMap的長度是有限的,當插入的Entry越來越多時,再完美的Hash函數也難免會出現index衝突的情況。

a)開放地址法

這個方法的基本思想是:

  • 當發生地址衝突時,按照某種方法繼續探測哈希表中的其他存儲單元,直到找到空位置爲止。

這個過程可用下式描述:

Hi (key) = ( H (key)+ di ) mod m ( i = 1,2,……,k (k ≤ m – 1) )

  • 其中:H (key)爲關鍵字 key的直接哈希地址,m爲哈希表的長度, di 爲每次再探測時的地址增量。
  • 採用這種方法時,首先計算出元素的直接哈希地址 H (key),如果該存儲單元已被其他元素佔用,則繼續查看地址爲 H (key) + d2 的存儲單元,如此重複直至找到某個存儲單元爲空時,將關鍵字爲 key 的數據元素存放到該單元。
  • 增量 d 可以有不同的取法,並根據其取法有不同的稱呼:
    (1) di = 1 , 2 , 3 , …… 線性探測再散列
    (2) di = 1^2 ,- 1^2 , 2^2 ,- 2^2 , k^2, -k^2…… 二次探測再散列
    (3) di = 僞隨機序列 僞隨機再散列

例1 設有哈希函數 H (key) = key mod 7 ,哈希表的地址空間爲 0 ~ 6,對關鍵字序列( 32 , 13 , 49 , 55 , 22 , 38 , 21 )按線性探測再散列和二次探測再散列的方法分別構造哈希表。
解:
(1)線性探測再散列:

  • 32 % 7 = 4 ; 13 % 7 = 6 ; 49 % 7 = 0 ;
  • 55 % 7 = 6 發生衝突,下一個存儲地址( 6+1 )% 7 = 0 ,仍然發生衝突,再下一個存儲地址:( 6+2 )% 7 = 1 未發生衝突,可以存入。
  • 22 % 7 = 1 發生衝突,下一個存儲地址是:( 1 + 1 )% 7 = 2 未發生衝突;
  • 38 % 7 = 3 ;
  • 21 % 7 = 0 發生衝突,按照上面方法繼續探測直至空間 5 ,不發生衝突,所得到的哈希表對應存儲位置:
  • 下標: 0 1 2 3 4 5 6
  • 49 55 22 38 32 21 13

(2)二次探測再散列:

  • 下標: 0 1 2 3 4 5 6
  • 49 22 21 38 32 55 13

注意👮:對於利用開放地址法處理衝突所產生的哈希表中刪除一個元素時需要謹慎,不能直接地刪除,因爲這樣將會截斷其他具有相同哈希地址的元素的查找地址,所以,通常採用設定一個特殊的標誌以示該元素已被刪除。

b)再哈希法

  • 當發生衝突時,使用第二個、第三個、哈希函數計算地址,直到無衝突時。缺點:計算時間增加。
  • 比如上面第一次按照姓首字母進行哈希,如果產生衝突可以按照姓字母首字母第二位進行哈希,再衝突,第三位,直到不衝突爲止。

c)鏈地址法

將所有關鍵字爲同義詞的記錄存儲在同一線性鏈表中。

如下:
在這裏插入圖片描述

d)建立一個公共溢出區

  • 假設哈希函數的值域爲[0,m-1],則設向量HashTable[0..m-1]爲基本表,另外設立存儲空間向量OverTable[0..v]用以存儲發生衝突的記錄。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章