1. 程式人生 > >解決Hash碰撞衝突方法總結

解決Hash碰撞衝突方法總結

Hash碰撞衝突

我們知道,物件Hash的前提是實現equals()和hashCode()兩個方法,那麼HashCode()的作用就是保證物件返回唯一hash值,但當兩個物件計算值一樣時,這就發生了碰撞衝突。如下將介紹如何處理衝突,當然其前提是一致性hash。 1.開放地址法

開放地執法有一個公式:Hi=(H(key)+di) MOD m i=1,2,…,k(k<=m-1) 其中,m為雜湊表的表長。di 是產生衝突的時候的增量序列。如果di值可能為1,2,3,…m-1,稱線性探測再雜湊。 如果di取1,則每次衝突之後,向後移動1個位置.如果di取值可能為1,-1,2,-2,4,-4,9,-9,16,-16,…kk,-k

k(k<=m/2),稱二次探測再雜湊。 如果di取值可能為偽隨機數列。稱偽隨機探測再雜湊。 2.再雜湊法

當發生衝突時,使用第二個、第三個、雜湊函式計算地址,直到無衝突時。缺點:計算時間增加。 比如上面第一次按照姓首字母進行雜湊,如果產生衝突可以按照姓字母首字母第二位進行雜湊,再衝突,第三位,直到不衝突為止 3.鏈地址法(拉鍊法) 在這裡插入圖片描述

將所有關鍵字為同義詞的記錄儲存在同一線性連結串列中。如下:

因此這種方法,可以近似的認為是筒子裡面套筒子 4.建立一個公共溢位區

假設雜湊函式的值域為[0,m-1],則設向量HashTable[0…m-1]為基本表,另外設立儲存空間向量OverTable[0…v]用以儲存發生衝突的記錄。 拉鍊法的優缺點:

優點: ①拉鍊法處理衝突簡單,且無堆積現象,即非同義詞決不會發生衝突,因此平均查詢長度較短; ②由於拉鍊法中各連結串列上的結點空間是動態申請的,故它更適合於造表前無法確定表長的情況; ③開放定址法為減少衝突,要求裝填因子α較小,故當結點規模較大時會浪費很多空間。而拉鍊法中可取α≥1,且結點較大時,拉鍊法中增加的指標域可忽略不計,因此節省空間; ④在用拉鍊法構造的散列表中,刪除結點的操作易於實現。只要簡單地刪去連結串列上相應的結點即可。而對開放地址法構造的散列表,刪除結點不能簡單地將被刪結 點的空間置為空,否則將截斷在它之後填人散列表的同義詞結點的查詢路徑。這是因為各種開放地址法中,空地址單元(即開放地址)都是查詢失敗的條件。因此在 用開放地址法處理衝突的散列表上執行刪除操作,只能在被刪結點上做刪除標記,而不能真正刪除結點。

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