1. 程式人生 > >雜湊衝突詳解、拉鍊法、開地址法

雜湊衝突詳解、拉鍊法、開地址法

雜湊衝突詳解

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


  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接近的素數。
    
  • 二次探查法詳解

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

  • 雙雜湊法詳解

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