hash沖突及解決方法(平均查找長度?)

一、什么是hash沖突?

假設(shè)hash表的大小為9(即有9個槽),現(xiàn)在要把一串?dāng)?shù)據(jù)存到表里:5,28,19,15,20,33,12,17,10

簡單計算一下:hash(5)=5, 所以數(shù)據(jù)5應(yīng)該放在hash表的第5個槽里;hash(28)=1,所以數(shù)據(jù)28應(yīng)該放在hash表的第1個槽里;hash(19)=1,也就是說,數(shù)據(jù)19也應(yīng)該放在hash表的第1個槽里——于是就造成了碰撞(也稱為沖突,collision)。

二、Hash沖突解決方法:

1.開放定址法(再散列法):?

基本思想:當(dāng)關(guān)鍵字key的哈希地址p=H(key)出現(xiàn)沖突時,以p為基礎(chǔ),產(chǎn)生另一個哈希地址p1,如果p1仍然沖突,再以p為基礎(chǔ),產(chǎn)生另一個哈希地址p2,…, ? ? ? ? ? ? ? ? ? ? ? ? ? ?直到找出一個不沖突的哈希地址pi ,將相應(yīng)元素存入其中。

這種方法有一個通用的再散列函數(shù)形式:

Hi=(H(key)+di)% m ? i=1,2,…,n

其中H(key)為哈希函數(shù),m 為表長,di稱為增量序列。增量序列的取值方式不同,相應(yīng)的再散列方式也不同。

(1).線性探測再散列:

dii=1,2,3,…,m-1

沖突發(fā)生時,順序查看表中下一單元,直到找出一個空單元或查遍全表。

(2).二次探測再散列:?

di=12,-12,22,-22,…,k2,-k2 ? ?( k<=m/2 )

沖突發(fā)生時,在表的左右進行跳躍式探測,比較靈活。

(3).偽隨機探測再散列:?

di=偽隨機數(shù)序列。

具體實現(xiàn)時,應(yīng)建立一個偽隨機數(shù)發(fā)生器,(如i=(i+p) % m),并給定一個隨機數(shù)做起點。

4.? 示例:

?已知哈希表長度m=11,哈希函數(shù)為:H(key)= key ?% ?11,則H(47)=3,H(26)=4,H(60)=5,假設(shè)下一個關(guān)鍵字為69,則H(69)=3,與47沖突。

a):?如果用線性探測再散列處理沖突,下一個哈希地址為H1=(3 + 1)% 11 = 4,仍然沖突,再找下一個哈希地址為H2=(3 + 2)% 11 = 5,還是沖突,

? ? ? ? ? ? ? ?繼續(xù)找下一個哈希地址為H3=(3 + 3)% 11 = 6,此時不再沖突,將69填入5號單元。

0 ? ? 1 ? ? 2 ? ? 3 ? ? 4 ? ? 5 ? ? 6 ? ? 7 ? ? 8 ? ? 9 ? ? 10

47 ? 26 ? 60 ? 69

b):?如果用二次探測再散列處理沖突,下一個哈希地址為H1=(3 + 12)% 11 = 4,仍然沖突,再找下一個哈希地址為H2=(3 - 12)% 11 = 2,此時不再沖突,

? ? ? ? ? ? ? ?將69填入2號單元。

0 ? ? 1 ? ? 2 ? ? 3 ? ? 4 ? ? 5 ? ? 6 ? ? 7 ? ? 8 ? ? 9 ? ? 10

69?? 47 ? 26 ?60

c):?如果用偽隨機探測再散列處理沖突,且偽隨機數(shù)序列為:2,5,9,……..,則下一個哈希地址為H1=(3 + 2)% 11 = 5,仍然沖突,再找下一個哈希地址

? ? ? ? ? ? ? ?為H2=(3 + 5)% 11 = 8,此時不再沖突,將69填入8號單元。

0 ? ? 1 ? ? 2 ? ? 3 ? ? 4 ? ? 5 ? ? 6 ? ? 7 ? ? 8 ? ? 9 ? ? 10

47 ? 26 ?60 ? ? ? ? ? ? ? ? ?69

2.再哈希法

這種方法是同時構(gòu)造多個不同的哈希函數(shù):

Hi=RH1(key) i=1,2,…,k

當(dāng)哈希地址Hi=RH1(key)發(fā)生沖突時,再計算Hi=RH2(key)……,直到?jīng)_突不再產(chǎn)生。這種方法不易產(chǎn)生聚集,但增加了計算時間。

3.鏈地址法 (HashMap的沖突處理方式)

這種方法的基本思想是將所有哈希地址為i的元素構(gòu)成一個稱為同義詞鏈的單鏈表,并將單鏈表的頭指針存在哈希表的第i個單元中,因而查找、插入和刪除主要在同義詞鏈中進行。鏈地址法適用于經(jīng)常進行插入和刪除的情況。

4.建立公共溢出區(qū)

這種方法的基本思想是:將哈希表分為基本表和溢出表兩部分,凡是和基本表發(fā)生沖突的元素,一律填入溢出表。

三、拉鏈法與開放地址法相比的缺點:

拉鏈法優(yōu)點:

拉鏈法處理沖突簡單,且無堆積現(xiàn)象,即非同義詞決不會發(fā)生沖突,因此平均查找長度較短;

由于拉鏈法中各鏈表上的結(jié)點空間是動態(tài)申請的,故它更適合于造表前無法確定表長的情況

③開放定址法為減少沖突,要求裝填因子α較小,故當(dāng)結(jié)點規(guī)模較大時會浪費很多空間。而拉鏈法中可取α≥1,且結(jié)點較大時,拉鏈法中增加的指針域可忽略不計,因此節(jié)省空間;

在用拉鏈法構(gòu)造的散列表中,刪除結(jié)點的操作易于實現(xiàn)。只要簡單地刪去鏈表上相應(yīng)的結(jié)點即可。而對開放地址法構(gòu)造的散列表,刪除結(jié)點不能簡單地將被刪結(jié) 點的空間置為空,否則將截斷在它之后填人散列表的同義詞結(jié)點的查找路徑。這是因為各種開放地址法中,空地址單元(即開放地址)都是查找失敗的條件。因此在 用開放地址法處理沖突的散列表上執(zhí)行刪除操作,只能在被刪結(jié)點上做刪除標記,而不能真正刪除結(jié)點。

拉鏈法缺點:

指針需要額外的空間,故當(dāng)結(jié)點規(guī)模較小時,開放定址法較為節(jié)省空間,而若將節(jié)省的指針空間用來擴大散列表的規(guī)模,可使裝填因子變小,這又減少了開放定址法中的沖突,從而提高平均查找速度。

四、不同處理沖突的平均查找長度

例:

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

(1)線性探測法:

查找成功時的查找次數(shù)等于插入元素時的比較次數(shù),查找成功的平均查找長度為:

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

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

查找不成功的平均查找次數(shù)為:

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

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

https://blog.csdn.net/u011080472/article/details/51177412

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容