哈希表——線性探測法、鏈地址法、查找成功、查找不成功的平均長度


一、哈希表

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

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM