哈希表的常見衝突檢測方法及其複雜度總結



一、哈希表

1、概念

       哈希表(Hash Table)也叫散列表,是根據關鍵碼值(Key Value)而直接進行訪問的數據結構。它通過把關鍵碼值映射到哈希表中的一個位置來訪問記錄,以加快查找的速度。這個映射函數就做散列函數,存放記錄的數組叫做散列表。

2、散列存儲的基本思路

       以數據中每個元素的關鍵字K爲自變量,通過散列函數H(k)計算出函數值,以該函數值作爲一塊連續存儲空間的的單元地址,將該元素存儲到函數值對應的單元中。

3、哈希表查找的時間複雜度

       哈希表存儲的是鍵值對,其查找的時間複雜度與元素數量多少無關,哈希表在查找元素時是通過計算哈希碼值來定位元素的位置從而直接訪問元素的,因此,哈希表查找的時間複雜度爲O(1)。


二、常用的哈希函數

1.   直接尋址法

取關鍵字或者關鍵字的某個線性函數值作爲哈希地址,即H(Key)=Key或者H(Key)=a*Key+b(a,b爲整數),這種散列函數也叫做自身函數.如果H(Key)的哈希地址上已經有值了,那麼就往下一個位置找,知道找到H(Key)的位置沒有值了就把元素放進去.

2.   數字分析法

分析一組數據,比如一組員工的出生年月,這時我們發現出生年月的前幾位數字一般都相同,因此,出現衝突的概率就會很大,但是我們發現年月日的後幾位表示月份和具體日期的數字差別很大,如果利用後面的幾位數字來構造散列地址,則衝突的機率則會明顯降低.因此數字分析法就是找出數字的規律,儘可能利用這些數據來構造衝突機率較低的散列地址.

3.   平方取中法

取關鍵字平方後的中間幾位作爲散列地址.一個數的平方值的中間幾位和數的每一位都有關。因此,有平方取中法得到的哈希地址同關鍵字的每一位都有關,是的哈希地址具有較好的分散性。該方法適用於關鍵字中的每一位取值都不夠分散或者較分散的位數小於哈希地址所需要的位數的情況。

4.   摺疊法

摺疊法即將關鍵字分割成位數相同的幾部分,最後一部分位數可以不同,然後取這幾部分的疊加和(注意:疊加和時去除進位)作爲散列地址.數位疊加可以有移位疊加和間界疊加兩種方法.移位疊加是將分割後的每一部分的最低位對齊,然後相加;間界疊加是從一端向另一端沿分割界來回摺疊,然後對齊相加.

5.   隨機數法

選擇一個隨機數,去關鍵字的隨機值作爲散列地址,通常用於關鍵字長度不同的場合.

6.   除留餘數法

取關鍵字被某個不大於散列表表長m的數p除後所得的餘數爲散列地址.即H(Key)=Key MOD p,p<=m.不僅可以對關鍵字直接取模,也可在摺疊、平方取中等運算之後取模。對p的選擇很重要,一般取素數或m,若p選得不好,則很容易產生衝突。一般p取值爲表的長度tableSize。


三、哈希衝突的處理方法

1、開放定址法——線性探測

線性探測法的地址增量di = 1, 2, ... , m-1,其中,i爲探測次數。該方法一次探測下一個地址,知道有空的地址後插入,若整個空間都找不到空餘的地址,則產生溢出。

線性探測容易產生“聚集”現象。當表中的第i、i+1、i+2的位置上已經存儲某些關鍵字,則下一次哈希地址爲i、i+1、i+2、i+3的關鍵字都將企圖填入到i+3的位置上,這種多個哈希地址不同的關鍵字爭奪同一個後繼哈希地址的現象稱爲“聚集”。聚集對查找效率有很大影響。

2、開放地址法——二次探測

二次探測法的地址增量序列爲 di = 12, -12, 22, -22,… , q2, -q(q <= m/2)。二次探測能有效避免“聚集”現象,但是不能夠探測到哈希表上所有的存儲單元,但是至少能夠探測到一半。

3、鏈地址法

鏈地址法也成爲拉鍊法。其基本思路是:將所有具有相同哈希地址的而不同關鍵字的數據元素連接到同一個單鏈表中。如果選定的哈希表長度爲m,則可將哈希表定義爲一個有m個頭指針組成的指針數組T[0..m-1],凡是哈希地址爲i的數據元素,均以節點的形式插入到T[i]爲頭指針的單鏈表中。並且新的元素插入到鏈表的前端,這不僅因爲方便,還因爲經常發生這樣的事實:新近插入的元素最優可能不久又被訪問。

鏈地址法特點

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

四、哈希表的裝填因子

裝填因子 = (哈希表中的記錄數) /  (哈希表的長度)

裝填因子是哈希表裝滿程度的標記因子。值越大,填入表中的數據元素越多,產生衝突的可能性越大。


五、不同處理衝突的平均查找長度

 

例:

假設散列表的長度是13,三列函數爲H(K) = k % 13,給定的關鍵字序列爲{32, 14, 23, 01, 42, 20, 45, 27, 55, 24, 10, 53}。分別畫出用線性探測法和拉鍊法解決衝突時構造的哈希表,並求出在等概率情況下,這兩種方法的查找成功和查找不成功的平均查找長度。

(1)線性探測法:

查找成功時的查找次數等於插入元素時的比較次數,查找成功的平均查找長度爲:

ASL = (1+2+1+4+3+1+1+3+9+1+1+3)/12 = 2.5

查找成功時的查找次數:第n個位置不成功時的比較次數爲,第n個位置到第1個沒有數據位置的距離:如第0個位置取值爲1,第1個位置取值爲2.

查找不成功的平均查找次數爲:

ASL = (1+2+3+4+5+6+7+8+9+10+11+12)/ 13 = 91/13

(2)鏈地址法

查找成功時的平均查找長度:

ASL = (1*6+2*4+3*1+4*1)/12 = 7/4

查找不成功時的平均查找長度:

ASL = (4+2+2+1+2+1)/13

注意:查找成功時,分母爲哈希表元素個數,查找不成功時,分母爲哈希表長度。

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