如何解決Hash衝突

2022-07-26 22:54:13 字數 2306 閱讀 9302

雜湊衝突相關介紹:

雜湊計算時努力把比較大的資料存放到相對較小的空間

最常見的雜湊演算法是取模法

取模法的計算過程:

比如陣列的長度是5,這是有乙個資料是6,那麼如何把這個6存放到長度只是5的資料中呢,安裝取模法,計算6%5,結果是1,那麼就把6放到資料下標是1的位置,那麼7就應該放在2這個位置,到此位置,雜湊衝突還沒有出現,這是有個資料11,按照取模法,11%5 = 1,也等於1,那麼原來資料下標是1的地方已經有數了,是6,這時又計算出1這個位置,那麼陣列是1的位置,就必須儲存兩個數,這是就叫雜湊衝突,衝突之後就要按照順序來存放了,如果資料分布比較廣泛,而且儲存資料的資料長度比較大,那麼雜湊衝突就比較小,否則衝突是很高的,

通過構造效能良好的雜湊函式,可以減少衝突,但一般不可能完全避免衝突,因此解決衝突是雜湊法的另乙個關鍵問題。建立雜湊表和查詢雜湊表都會遇到衝突,兩種情況下解決衝突的方法應該一致。下面以建立雜湊表為例,說明解決衝突的方法。常用的解決衝突方法有以下四種:

這種方法也稱再雜湊法,其基本思想是:當關鍵字key的雜湊位址p=h(key)出現衝突時,以p為基礎,產生另乙個雜湊位址p1,如果p1仍然衝突,再以p為基礎,產生另乙個雜湊位址p2,…,直到找出乙個不衝突的雜湊位址pi ,將相應元素存入其中。這種方法有乙個通用的再雜湊函式形式:

hi=(h(key)+di)% m i=1,2,…,n

其中h(key)為雜湊函式,m 為表長,di稱為增量序列。增量序列的取值方式不同,相應的再雜湊方式也不同。主要有以下三種:

1.1 線性探測再雜湊

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

1.2 二次探測再雜湊

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

這種方法的特點是:衝突發生時,在表的左右進行跳躍式探測,比較靈活。

例如,已知雜湊表長度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號單元。

1)優點: ①記錄更容易進行序列化(serialize)操作 ②如果記錄總數可以預知,可以建立完美雜湊函式,此時處理資料的效率是非常高的

2)缺點: ①儲存記錄的數目不能超過桶陣列的長度,如果超過就需要擴容,而擴容會導致某次操作的時間成本飆公升,這在實時或者互動式應用中可能會是乙個嚴重的缺陷 ②使用探測序列,有可能其計算的時間成本過高,導致雜湊表的處理效能降低 ③由於記錄是存放在桶陣列中的,而桶陣列必然存在空槽,所以當記錄本身尺寸(size)很大並且記錄總數規模很大時,空槽占用的空間會導致明顯的記憶體浪費 ④刪除記錄時,比較麻煩。比如需要刪除記錄a,記錄b是在a之後插入桶陣列的,但是和記錄a有衝突,是通過探測序列再次跳轉找到的位址,所以如果直接刪除a,a的位置變為空槽,而空槽是查詢記錄失敗的終止條件,這樣會導致記錄b在a的位置重新插入資料前不可見,所以不能直接刪除a,而是設定刪除標記。這就需要額外的空間和操作。

這種方法是同時構造多個不同的雜湊函式:

hi=rh1(key) i=1,2,…,k

當雜湊位址hi=rh1(key)發生衝突時,再計算hi=rh2(key)……,直到衝突不再產生。這種方法不易產生聚集,但增加了計算時間。

這種方法的基本思想是將所有雜湊位址為i的元素構成乙個稱為同義詞鏈的單鏈表,並將單鏈表的頭指標存在雜湊表的第i個單元中,因而查詢、插入和刪除主要在同義詞鏈中進行。鏈位址法適用於經常進行插入和刪除的情況。

優缺點1)優點: ①對於記錄總數頻繁可變的情況,處理的比較好(也就是避免了動態調整的開銷) ②由於記錄儲存在結點中,而結點是動態分配,不會造成記憶體的浪費,所以尤其適合那種記錄本身尺寸(size)很大的情況,因為此時指標的開銷可以忽略不計了 ③刪除記錄時,比較方便,直接通過指標操作即可

2)缺點: ①儲存的記錄是隨機分布在記憶體中的,這樣在查詢記錄時,相比結構緊湊的資料型別(比如陣列),雜湊表的跳轉訪問會帶來額外的時間開銷 ②如果所有的 key-value 對是可以提前預知,並之後不會發生變化時(即不允許插入和刪除),可以人為建立乙個不會產生衝突的完美雜湊函式(perfect hash function),此時封閉雜湊的效能將遠高於開放雜湊 ③由於使用指標,記錄不容易進行序列化(serialize)操作

這種方法的基本思想是:將雜湊表分為基本表和溢位錶兩部分,凡是和基本表發生衝突的元素,一律填入溢位表。

如何解決hash衝突

1 衝突是如何產生的?上文中談到,雜湊函式是指如何對關鍵字進行編址的規則,這裡的關鍵字的範圍很廣,可視為無限集,如何保證無限集的原資料在編址的時候不會出現重複呢?規則本身無法實現這個目的。舉乙個例子,仍然用班級同學做比喻,現有如下同學資料 張三,李四,王五,趙剛,吳露.假如我們編址規則為取姓氏中姓的...

如何解決雜湊衝突

就不自己寫了,直接貼下吧 看了concurrenthashmap的實現,使用的是拉鍊法.雖然我們不希望發生衝突,但實際上發生衝突的可能性仍是存在的。當關鍵字值域遠大於雜湊表的長度,而且事先並不知道關鍵字的具體取值時。衝突就難免會發 生。另外,當關鍵字的實際取值大於雜湊表的長度時,而且表中已裝滿了記錄...

svn 如何解決衝突

專案中,往往不止你一人開發,多人開發,難免會有 的衝突。彼此間誰也不能保證不會修改同個檔案。如果修改了同個方法的內容。這時提交到svn是會提示 衝突的。當然,衝突是可控的,但不能避免。每次寫 的時候,標準的姿勢是先update,再修改提交。下面,我們說下衝突後該如何解決?檔案衝突格式如下 code ...