java,Hash衝突及解決辦法

Hash衝突:

理解Hash衝突前,先了解一下Hash函數

哈希函數
數據元素的存儲地址,是根據數據的關鍵字K通過一定的函數關係計算得出,這個函數關係即稱哈希函數。

Hash衝突就是,不同的數據元素關鍵字K,計算出的哈希值相同,此時兩個或多個數據,對應同一個存儲地址,即產生衝突。

Hash衝突解決辦法:
  1. 開放定址法
  2. 再哈希法
  3. 鏈地址法
  4. 建立公共溢出區

開放定址法
使用某種探測算法在散列表中尋找下一個空的散列地址,只要散列表足夠大,空的散列地址總能找到。按照探測序列的方法,一般將開放地址法區分爲線性探查法(順序的查看下一個單元)、二次探查法(在表的左右進行跳躍式探測)、雙重散列法(雙哈希函數,先用第一個函數 f(key) 對關鍵碼計算哈希地址,一旦產生地址衝突,再用第二個函數 g(key) 確定移動的步長因子,最後通過步長因子序列由探測函數尋找空的哈希地址)、僞隨機探測再散列建立一個僞隨機數發生器,並給一個隨機數作爲起點()等。
** 再哈希法**
這種方式是同時構造多個哈希函數,當產生衝突時,計算另一個哈希函數的值。
這種方法不易產生聚集,但增加了計算時間。
鏈地址法
將所有哈希地址相同的都鏈接在同一個鏈表中 ,因而查找、插入和刪除主要在同義詞鏈中進行。鏈地址法適用於經常進行插入和刪除的情況。
在這裏插入圖片描述在這裏插入圖片描述
注意:最壞的就是hash值全都映射在同一個地址上,這樣哈希表就會退化成鏈表
jdk1.8採用紅黑樹解決這種情況

建立公共溢出區
將哈希表分爲基本表和溢出表兩部分,凡是和基本表發生衝突的元素,一律填入溢出表。

優缺點比較:

開放散列(open hashing)/ 拉鍊法(針對桶鏈結構)
優點:
在總數頻繁變動的時候可以節省開銷,避免了動態調整;
記錄存儲在節點裏,動態分佈,避免了指針的開銷
刪除時候比較方便
缺點:
因爲存儲是動態的,所以在查詢的時候跳轉需要更多的時間的開銷
在key-value可以預知,以及沒有後續增改操作時候,封閉散列性能優於開放散列
不容易序列化

封閉散列(closed hashing)/ 開放定址法
優點:
容易序列化
如果可以預知數據總數,可以創建完美哈希數列
缺點:
存儲的記錄數目不能超過桶組數,在交互時候會非常麻煩
使用探測序列,計算時間成本過高
刪除的時候比較麻煩

發佈了48 篇原創文章 · 獲贊 13 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章