開位址法
基本思想:當關鍵碼key的雜湊位址h0 = hash(key)出現衝突時,以h0為基礎,產生另乙個雜湊位址h1 ,如果h1仍然衝突,再以h0
為基礎,產生另乙個雜湊位址h2 ,…,直到找出乙個不衝突的雜湊位址hi ,將相應元素存入其中。這種方法有乙個通用的再雜湊函
數形式:
其中h0 為hash(key) ,m為表長,di稱為增量序列。增量序列的取值方式不同,相應的再雜湊方式也不同。主要有以下四種:
線性探測再雜湊(一)、線性探測再雜湊二次探測再雜湊
偽隨機探測再雜湊
雙雜湊法
假設給出一組表項,它們的關鍵碼為 burke, ekers, broad, blum, attlee, alton, hecht, ederly。採用的雜湊函式是:取其第乙個字母在
字母表中的位置。
hash (x) = ord (x) - ord (『a』)
這樣,可得
hash (burke) = 1又設雜湊表為ht[26],m = 26。採用線性探查法處理溢位,則上述關鍵碼在雜湊表中雜湊位置如圖所示。紅色括號內的數字表示找hash (ekers) = 4
hash (broad) = 1
hash (blum) = 1
hash (attlee) = 0
hash (hecht) = 7
hash (alton) = 0
hash (ederly) = 4
到空桶時的探測次數。比如輪到放置blum 的時候,探測位置1,被佔據,接著向下探測位置2還是不行,最後放置在位置3,總的探
測次數是3。
堆積現象
雜湊位址不同的結點爭奪同乙個後繼雜湊位址的現象稱為堆積(clustering),比如alton 本來位置是0,直到探測了6次才找到合適位
置5。這將造成不是同義詞的結點也處在同乙個探測序列中,從而增加了探測序列長度,即增加了查詢時間。若雜湊函式不好、或裝
填因子a 過大,都會使堆積現象加劇。
下面給出具體的實現**,大體跟前面講過的鏈位址法差異不大,只是利用的結構不同,如下:
status 儲存狀態,有empty, deleted, active,刪除的時候只是邏輯刪除,即將狀態置為deleted,當插入新的key 時,只要不
是active 的位置都是可以放入,如果是deleted位置,需要將原來元素先釋放free掉,再插入。
二次探測再雜湊
為改善「堆積」問題,減少為完成搜尋所需的平均探查次數,可使用二次探測法。
通過某乙個雜湊函式對表項的關鍵碼 x 進行計算,得到桶號,它是乙個非負整數。
若設表的長度為tablesize = 23,則**性探測再雜湊 舉的例子中利用二次探查法所得到的雜湊結果如圖所示。
比如輪到放置blum 的時候,本來應該是位置1,已經被burke 佔據,接著探測 h0 + 1 = 2,,發現被broad 佔據,接著探測 h0 - 1 =
0,發現空位於是放進去,探測次數為3。
下面來看具體**實現,跟前面講過的線性探測再雜湊 差不多,只是探測的方法不同,但使用的資料結構也有點不一樣,此外還實
現了開裂,如果裝載因子 a > 1/2; 則建立新錶,將舊表內容拷貝過去,所以hash_t 結構體需要再儲存乙個size 成員,同樣的原因,
為了將舊表內容拷貝過去,hash_node_t 結構體需要再儲存 *key 和 *value 的size。
雜湊衝突之雜湊法
雜湊碰撞 雜湊衝突 不同的key值經過雜湊函式hash key 處理以後可能產生相同的值雜湊位址,我們稱這種情況為雜湊衝突。任意的雜湊函式都不能避免產生衝突。閉雜湊法 線性探測 void insert1 int x pos if pos v.capacity s pos exist v pos x ...
平方探測法處理雜湊函式衝突
平方探測法是一種較好的處理衝突的方法,可以避免出現 堆積 問題,它的缺點是不能探測到雜湊表上的所有單元,但至少能探測到一半單元。下面通過乙個例子來理解 設hash函式為 h key key mod 7,雜湊表的位址空間為0,1,10,開始時雜湊表為空,用平方探測法解決衝突,畫出依次插入鍵值9,14,...
雜湊 雜湊函式 衝突處理
例 如果我們現在要統計的是80後出生年份的人口數,那麼我們對出生年份這個關鍵字可以用年份減去1980來作為位址。此時f key key 1980。這樣的雜湊函式優點就是簡單 均勻,也不會產生衝突,但問題是這需要事先知道關鍵字的分布情況,適合查詢表較小且連續的情況。由於這樣的限制,在現實應用中,直接定...