目錄
開放定址法
線性探測再雜湊
二次探測再雜湊
偽隨機探測再雜湊
再雜湊法
鏈位址法
建立公共溢位區
優缺點 開放雜湊(open hashing)/ 拉鍊法(針對桶鏈結構)
封閉雜湊(closed hashing)/ 開放定址法
通過構造效能良好的雜湊函式,可以減少衝突,但一般不可能完全避免衝突,因此解決衝突是雜湊法的另乙個關鍵問題。建立雜湊表和查詢雜湊表都會遇到衝突,兩種情況下解決衝突的方法應該一致。下面以建立雜湊表為例,說明解決衝突的方法。常用的解決衝突方法有以下四種:
這種方法也稱再雜湊法,其基本思想是:當關鍵字
key的雜湊位址
p=h(
key)出現衝突時,以
p為基礎,產生另乙個雜湊位址
p1,如果
p1仍然衝突,再以
p為基礎,產生另乙個雜湊位址p2,
…,直到找出乙個不衝突的雜湊位址
pi ,
將相應元素存入其中。這種方法有乙個通用的再雜湊函式形式:
hi=(h(
key)
+di)
% m i=1,2
,…,n其中
h(key)為雜湊函式,
m 為表長,
di稱為增量序列。增量序列的取值方式不同,相應的再雜湊方式也不同。主要有以下三種:
dii=1,2
,3,…
,m-1
這種方法的特點是:衝突發生時,順序檢視表中下一單元,直到找出乙個空單元或查遍全表。
di=12
,-12,22
,-22,…
,k2,-k2 ( k<=m/2 )
這種方法的特點是:衝突發生時,在表的左右進行跳躍式探測,比較靈活。
di=偽隨機數序列。
具體實現時,應建立乙個偽隨機數發生器,(如
i=(i+p) % m
),並給定乙個隨機數做起點。
例如,已知雜湊表長度
m=11
,雜湊函式為:h(
key)
= key % 11,則h
(47)=3
,h(26
)=4,h
(60)=5
,假設下乙個關鍵字為
69,則h(
69)=3,與
47衝突。
如果用線性探測再雜湊處理衝突,下乙個雜湊位址為
h1=(
3 + 1
)% 11 = 4
h2=(
3 + 2
)% 11 = 5
h3=(
3 + 3
)% 11 = 6
,此時不再衝突,將
69填入
5號單元
。如果用二次探測再雜湊處理衝突,下乙個雜湊位址為
h1=(
3 + 12
)% 11 = 4
h2=(
3 - 12
)% 11 = 2
,此時不再衝突,將
69填入
2號單元
。如果用偽隨機探測再雜湊處理衝突,且偽隨機數序列為:2,
5,9,
……..
h1=(
3 + 2
)% 11 = 5
h2=(
3 + 5
)% 11 = 8
,此時不再衝突,將
69填入
8號單元
。 這種方法是同時構造多個不同的雜湊函式:
hi=rh1
(key
)i=1,2
,…,k
當雜湊位址
hi=rh1
(key
)發生衝突時,再計算
hi=rh2
(key
)……,直到衝突不再產生。這種方法不易產生聚集,但增加了計算時間。
這種方法的基本思想是將所有雜湊位址為
i的元素構成乙個稱為同義詞鏈的單鏈表,並將單鏈表的頭指標存在雜湊表的第
i個單元中,因而查詢、插入和刪除主要在同義詞鏈中進行。鏈位址法適用於經常進行插入和刪除的情況。
這種方法的基本思想是:將雜湊表分為基本表和溢位錶兩部分,凡是和基本表發生衝突的元素,一律填入溢位表。
1)優點: ①對於記錄總數頻繁可變的情況,處理的比較好(也就是避免了動態調整的開銷) ②由於記錄儲存在結點中,而結點是動態分配,不會造成記憶體的浪費,所以尤其適合那種記錄本身尺寸(size)很大的情況,因為此時指標的開銷可以忽略不計了 ③刪除記錄時,比較方便,直接通過指標操作即可
2)缺點: ①儲存的記錄是隨機分布在記憶體中的,這樣在查詢記錄時,相比結構緊湊的資料型別(比如陣列),雜湊表的跳轉訪問會帶來額外的時間開銷 ②如果所有的 key-value 對是可以提前預知,並之後不會發生變化時(即不允許插入和刪除),可以人為建立乙個不會產生衝突的完美雜湊函式(perfect hash function),此時封閉雜湊的效能將遠高於開放雜湊 ③由於使用指標,記錄不容易進行序列化(serialize)操作
1)優點: ①記錄更容易進行序列化(serialize)操作 ②如果記錄總數可以預知,可以建立完美雜湊函式,此時處理資料的效率是非常高的
2)缺點: ①儲存記錄的數目不能超過桶陣列的長度,如果超過就需要擴容,而擴容會導致某次操作的時間成本飆公升,這在實時或者互動式應用中可能會是乙個嚴重的缺陷 ②使用探測序列,有可能其計算的時間成本過高,導致雜湊表的處理效能降低 ③由於記錄是存放在桶陣列中的,而桶陣列必然存在空槽,所以當記錄本身尺寸(size)很大並且記錄總數規模很大時,空槽占用的空間會導致明顯的記憶體浪費 ④刪除記錄時,比較麻煩。比如需要刪除記錄a,記錄b是在a之後插入桶陣列的,但是和記錄a有衝突,是通過探測序列再次跳轉找到的位址,所以如果直接刪除a,a的位置變為空槽,而空槽是查詢記錄失敗的終止條件,這樣會導致記錄b在a的位置重新插入資料前不可見,所以不能直接刪除a,而是設定刪除標記。這就需要額外的空間和操作。
快速解決Hash碰撞衝突的方法小結
hash碰撞衝突 我們知道,物件hash的前提是實現equals 和hashcode 兩個方法,那麼hashcode 的作用就是保證物件返回唯一hash值,但當兩個物件計算值一樣時,這就發生了碰撞衝突。如下將介紹如何處理衝突,當然其前提是一致性hash。1.開放位址法 開放地執法有乙個公式 hi h...
hash,解決hash衝突的方法
數字分析法 平方取中法 除留餘數法 偽隨機數法 線性探測 二次探測 偽隨機數探測 拉鍊探測。如果負載因子是預設的0.75,hashmap 16 的時候,佔16個記憶體空間,實際上只用到了12個,超過12個就擴容。如果負載因子是1的話,hashmap 16 的時候,佔16個記憶體空間,實際上會填滿16...
Hash衝突解決方法
當關鍵字值域遠大於雜湊表的長度,而且事先並不知道關鍵字的具體取值時。衝突就難免會發 生。另外,當關鍵字的實際取值大於雜湊表的長度時,而且表中已裝滿了記錄,如果插入乙個新記錄,不僅發生衝突,而且還會發生溢位。因此,處理衝突和溢位是 雜湊技術中的兩個重要問題。1.開放位址法 開放位址法公式 h h ke...