Java集合(九)哈希沖突及解決哈希沖突的4種方式


Java集合(九)哈希沖突及解決哈希沖突的4種方式

一、哈希沖突

(一)、產生的原因

哈希是通過對數據進行再壓縮,提高效率的一種解決方法。但由於通過哈希函數產生的哈希值是有限的,而數據可能比較多,導致經過哈希函數處理后仍然有不同的數據對應相同的哈希值。這時候就產生了哈希沖突。

(二)、因素

  • 裝填因子(裝填因子=數據總數 / 哈希表長);
  • 哈希函數;
  • 處理沖突的方法。

(三)、解決哈希沖突的4中方式

開放地址法;再哈希法;鏈地址法(拉鏈法);公共溢出區法。

二、開放地址法

開放地址法處理沖突的基本原則就是出現沖突后按照一定算法查找一個空位置存放。公式:


其中:Hi為計算出的地址,h(key)為哈希方法,di增量序列1,2,3,...,k(k<= m - 1),m為哈希表的長度。 

假設問題:關鍵碼集合為:{38,25,74,63,52,48,55},m = 7,采用除留余數法h(key) = key mod 7,並存儲在哈希表中。

(一)、線性探測:依次向后查找

從上圖可以看出,38和52存放3號地址沖突,25和74存放4地址沖突,根據集合,可以知道,38先存放在了3,25先存放了4,所以將74和52進行線上探測,根據公式,線上探測74時,取d = 1,探測52時,取d = 5,最終結果如下表:

優點:只要哈希表未被填滿,保證能找到一個空地址單元存放有沖突的元素。

缺點:能使第i個哈希地址的同義詞存入第i+1個地址,這樣本應存入第i+1個哈希地址的元素變成了第i+2個哈希地址的同義詞,產生“聚集”現象,降低查找效率。

(二)、二次探測:依次向前后查找,增量為1、2、3的二次方

以上面(一)線上探測74為例,根據公式,取d = 1²,最終結果如下表:

(三)、偽隨機探測:隨機產生一個增量位移

還是以74為例,根據公式,取d = 29時,最終結果如下表:

(四)、建立哈希表的步驟

1、取數據元素的關鍵碼key,計算其哈希函數值(地址)。若該地址對應的存儲 空間還沒有被占用,則將該元素存入;否則執行2解決沖突。

2、根據選擇的沖突處理方法,計算關鍵碼key的下一個存儲地址。若下一個存儲地址仍被占用,則繼續執行2,直到找到能用的存儲地址為止。

三、再哈希法

再哈希法,又叫雙哈希法,有多個不同的Hash函數,出現沖突后采用其他的哈希函數計算,直到不再沖突為止。雖然不易發生聚集,但是增加了計算時間。公式:

其中RHi為不同的哈希函數。比如乘余取整法:RH(k)=[b ×(a × k mod 1)] ,還是以上面74為例:設b = 10,a = 0.6180339,根據公式有:RH(74)=[10 ×(0.6180339 × 74 mod 1)]  = 7,最終結果如下表:

四、拉鏈法(鏈地址法)

將具有相同哈希地址的記錄鏈成一個單鏈表,m個哈希地址就設m個單鏈表,,然后用一個數組將m個單鏈表的表頭指針存儲起來,形成一個動態的結構。

優點:

1、拉鏈法處理沖突簡單,且無堆積現象,即非同義詞決不會發生沖突,因此平均查找長度較短;

  2、由於拉鏈法中各鏈表上的結點空間是動態申請的,故它更適合於造表前無法確定表長的情況;

  3、開放定址法為減少沖突,要求裝填因子α較小,故當結點規模較大時會浪費很多空間。而拉鏈法中可取α≥1,且結點較大時,拉鏈法中增加的指針域可忽略不計,因此節省空間;

  4、在用拉鏈法構造的散列表中,刪除結點的操作易於實現。只要簡單地刪去鏈表上相應的結點即可。

缺點:

1、指針占用較大空間時,會造成空間浪費,若空間用於增大散列表規模進而提高開放地址法的效率。

假設:關鍵字集合{47,7,29,11,16,92,22,8,3,50,37,89},m = 11,哈希算法為H(k) = k mod 11,則建表如下圖:

(一)、建立哈希表的步驟

1、取數據元素的關鍵碼key,計算其哈希函數值(地址)。若該地址對應的鏈表為空,則將該元素插入此鏈表;否則執行2解決沖突。

2、根據選擇的沖突處理方法,計算關鍵碼key的下一個存儲地址。若該地址對應的鏈表不為空,則利用鏈表的前插法或后插法將該元素插入此鏈表。

(二)、特點

1、非同義詞不會沖突,無“聚集”現象;

2、鏈表上的結點空間動態申請,適用於表長不確定的情況。

五、公共溢出區法

創建哈希表時,將所有產生沖突的的同義詞集中放在一個溢出表中。假設哈希函數的值域是[1,m-1],則設哈希表HashTable[0...m-1]為基本表,每個分量存放一個記錄,另外設溢出表OverTable[0,v]為溢出表,所有關鍵字和基本表中關鍵字為同義詞的記錄,不管它們由哈希函數得到的哈希地址是什么,一旦發生沖突,都填入溢出表。


例子:關鍵碼集合{26,36,41,38,44,15,68,12,6,51,25},m = 12,哈希函數:H(k)= k mod 12,則哈希表如下:

上圖藍色部分,元素的哈希地址沖突了,此時創建一個溢出表:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM