解決哈希衝突,拉鍊法,開地址法等

本文轉自https://blog.csdn.net/lyp_558/article/details/49499035

哈希衝突詳解


我喜歡用問答的形式來學習,這樣可以明確許多不明朗的問題。

 


  1. 什麼是哈希衝突?

 

比如我們要去買房子,本來已經看好的房子卻被商家告知那間房子已經被其他客戶買走了。這就是生活中實實在在的衝突問題。

同樣的當數據插入到哈希表時,不同key值產生的h(key)卻是相等的,這個時候就產生了衝突。這個時候就要解決這個問題。

  • 怎麼解決哈希衝突?

    方法1:拉鍊法 
    方法2:開地址法

  • 何爲拉鍊法?

    拉鍊法是解決哈希衝突的一種行之有效的方法,某些哈希地址可以被多個關鍵字值共享,這樣可以針對每個哈希地址建立一個單鏈表。

    在拉鍊(單鏈表)的哈希表中搜索一個記錄是容易的,首先計算哈希地址,然後搜索該地址的單鏈表。

    在插入時應保證表中不含有與該關鍵字值相同的記錄,然後按在有序表中插入一個記錄的方法進行。針對關鍵字值相同的情況,現行的處理方法是更新該關鍵字值中的內容。

    刪除關鍵字值爲k的記錄,應先在該關鍵字值的哈希地址處的單鏈表中找到該記錄,然後刪除之。

  • 什麼是開地址法?

    首先該方法並不建立鏈表。哈希表由M個元素組成,其地址從0到M-1。我們通過從空表開始,逐個向表中插入新記錄的方式建立散列表。 
    插入關鍵字值爲key的新紀錄的方法是: 
    從h(key)開始,按照某種規定的次序探查插入新記錄的空位置。h(key)被稱爲基位置。如果h(key)已經被佔用,那麼需要用一種解決衝突的策略來確定如何探查下一個空位置,所以這種方法又稱爲空缺編址法。 
    根據不同的解決衝突的策略,可以產生不同的需要被檢查的位置序列,稱爲 探查序列。 
    根據生成的探查序列的不同規則,可以有 線性探查法僞隨機探查法二次探查法 和 雙散列法等開址方法。

  • 線性探查法詳解

    缺點:線性探查法在情況不好的時候導致許多記錄在散列表中連成一片,從而使探查次數增加,影響搜索效率。這種現象稱爲基本聚集

    線性探查法是一種簡單的開地址方法,它使用下列循環探查序列:

    h(key),h(key)+1,...,M-1,0,...,h(key)-1

    從基位h(key)開始探查該位置是否被佔用,即是否爲空位置。 
    如果被佔用,則繼續探查位置h(key)+1,若該位置也已佔用,再根據探查序列中的規定繼續檢查下一個位置。 
    因此,探查序列爲:

    h(i) = (h(x)+i) % M (i=0,1,2,...,M-1)
  • 僞隨機法詳解

    僞隨機法是爲了消除線性探查的基本聚集而提出來的方法。其基本思想是建立一個僞隨機數發生器。當發生衝突時,就利用僞隨機數發生器計算下一個探查位置。僞隨機數發生器有不同的構造。

    一個比較簡單的僞隨機數產生方法:

       
       y(0) = h(key)
       y(i+1) = (y(i)+p) % M  (i=0,1,2,...)
    式中,y(0)爲僞隨機數發生器的初值,M爲哈希表的長度,
    P爲與M接近的素數。
    
  • 二次探查法詳解

    二次探查法也能夠消除基本聚集,雖然僞隨機數法和二次探查法都能夠消除基本聚集。但是如果兩個關鍵字值有相同的基本位置,那麼它們就會有相同的探查序列。這是因爲僞隨機數法和二次探查產生的探查序列是基位置的函數,而不是原來關鍵字的函數,因此由產生了二次聚集的問題。

  • 雙散列法詳解 

    使用雙散列方法可以避免二級聚集。雙散列法使用兩個散列函數,第一個散列函數計算探針序列的起始值,第二個散列函數計算下一個位置的探查步長。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章