4.解決Hash衝突的幾種方法

開放地址法:

1.線性探測法:ThreadLocalMap

       線性再散列法是形式最簡單的處理衝突的方法。插入元素時,如果發生衝突,算法會簡單的從該槽位置向後循環遍歷hash表,直到找到表中的下一個空槽,並將該元素放入該槽中(會導致相同hash值的元素挨在一起和其他hash值對應的槽被佔用)。查找元素時,首先散列值所指向的槽,如果沒有找到匹配,則繼續從該槽遍歷hash表,直到:(1)找到相應的元素;(2)找到一個空槽,指示查找的元素不存在,(所以不能隨便刪除元素);(3)整個hash表遍歷完畢(指示該元素不存在並且hash表是滿的)

用線性探測法處理衝突,思路清晰,算法簡單,但存在下列缺點:
① 處理溢出需另編程序。一般可另外設立一個溢出表,專門用來存放上述哈希表中放不下的記錄。此溢出表最簡單的結構是順序表,查找方法可用順序查找。
② 按上述算法建立起來的哈希表,刪除工作非常困難。如果將此元素刪除,查找的時會發現空槽,則會認爲要找的元素不存在。只能標上已被刪除的標記,否則,將會影響以後的查找。
③ 線性探測法很容易產生堆聚現象。所謂堆聚現象,就是存入哈希表的記錄在表中連成一片。按照線性探測法處理衝突,如果生成哈希地址的連續序列愈長 ( 即不同關鍵字值的哈希地址相鄰在一起愈長 ) ,則當新的記錄加入該表時,與這個序列發生衝突的可能性愈大。因此,哈希地址的較長連續序列比較短連續序列生長得快,這就意味着,一旦出現堆聚 ( 伴隨着衝突 ) ,就將引起進一步的堆聚。


2.線性補償探測法
線性補償探測法的基本思想是:將線性探測的步長從 1 改爲 Q ,即將上述算法中的
hash = (hash + 1) % m 改爲:hash = (hash + Q) % m = hash % m + Q % m,而且要求 Q 與 m 是互質的,以便能探測到哈希表中的所有單元。
【例】 PDP-11 小型計算機中的彙編程序所用的符合表,就採用此方法來解決衝突,所用表長 m = 1321 ,選用 Q = 25 。

3.僞隨機探測
隨機探測的基本思想是:將線性探測的步長從常數改爲隨機數,即令: hash = (hash + RN) % m ,其中 RN 是一個隨機數。在實際程序中應預先用隨機數發生器產生一個隨機序列,將此序列作爲依次探測的步長。這樣就能使不同的關鍵字具有不同的探測次序,從而可以避 免或減少堆聚。基於與線性探測法相同的理由,在線性補償探測法和隨機探測法中,刪除一個記錄後也要打上刪除標記。

拉鍊法
拉鍊法 : hashmap

拉鍊法的優點
與開放定址法相比,拉鍊法有如下幾個優點:
①拉鍊法處理衝突簡單,且無堆積現象,即非同義詞決不會發生衝突,因此平均查找長度較短;
②由於拉鍊法中各鏈表上的結點空間是動態申請的,故它更適合於造表前無法確定表長的情況;
③開放定址法爲減少衝突,要求裝填因子α較小,故當結點規模較大時會浪費很多空間。而拉鍊法中可取α≥1,且結點較大時,拉鍊法中增加的指針域可忽略不計,因此節省空間;
④在用拉鍊法構造的散列表中,刪除結點的操作易於實現。只要簡單地刪去鏈表上相應的結點即可。

拉鍊法的缺點
     拉鍊法的缺點是:指針需要額外的空間,故當結點規模較小時,開放定址法較爲節省空間,而若將節省的指針空間用來擴大散列表的規模,可使裝填因子變小,這又減少了開放定址法中的衝突,從而提高平均查找速度。

再散列(雙重散列,多重散列)
當發生衝突時,使用第二個、第三個、哈希函數計算地址,直到無衝突時。缺點:計算時間增加。

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