hash table碰撞處理

有兩種策略來解決hash table的碰撞問題。第一種策略是open addressing,如果數組中當前位置已經被佔用,他會爲當前數據重新選擇一個位置;第二種策略是separate chaining,在數組每一個位置安放一個鏈表。

1.Open Addressing

如果當前數據所修位置被佔用,該策略會爲數據重新選擇一個位置。這種測略有三種方法可以使用:

a.Liner probing

這種方法簡單的以當前位置爲起點,線性搜索空閒位置。如果hash函數選擇了第n個位置給當前數據,但是n位置已經被佔用,該方法將會嘗試n+1,n+2.........,知道找到一個空閒位置,如果到達數組末尾,則從數組頭繼續搜索。這個嘗試不同位置的過程叫做probing。

之所以叫做Liner probing,是因爲這個過程看起來像線性搜索。

當需要在hash table中搜索數據時候,同樣要是用probing,當通過key來搜索數據,且hash函數得到的位置是x,如果x位置包含其他的數據,那麼繼續搜索x+1,x+2,直到搜索到目標元素,或者x+k位置爲空,或者又重新便利到x位置。

Liner probing的問題是clustering(聚合),數據元素成塊狀分佈。如果插入一個映射到x位置的值,但是x被佔用了,插入方法將嘗試x+1。如果下一個元素被映射到x+1,而這個位置被佔用了,那他就得繼續往後嘗試。數據將會聚集成一塊一塊的。在實際應用中,如果插入數據相似,那麼會產生數據聚合,導致搜索和插入數據效率下降。

解決這個問題的方法是move ahead,不僅僅是前移一個元素位置。在quadratic probing中,插入方法將嘗試x+1^2,x+2^2,x+3^2.........直到找到空閒位置,在查找時候也要這麼做。


b.Quadratic probing

Quadratic probing的好處是可以降低clustering,因爲probing的偏移是n^2,而不是1,不會使得數據很接近。但是如果很多數據同時被映射到同一個位置上,那麼這種方法也是於事無補的。當有很多數據被映射到同一個位置時候,他將會嘗試x+1,x+4,x+9...............這將使數據查找變得困難。


c.double hashing

double hashing中,probing的偏移取決於key value自己。當key映射到位置x,而x已經被佔用的時候,則用第二個hash函數對key進行處理得到y,嘗試x+y,x+2y,x

+3y..........直到找到一個可以插入的位置。選擇第二個hash函數的目標是:hash函數值永遠大於等於1,對於key的得到的hash結果和第一個hash函數不同。通常,第二個hash函數這麼寫:

probe offset  =  c - key%c,    c是一個小於數組大小的常數


2.Separate chaining

這種方法在數組的每一個位置上用一個鏈表

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章