雜湊表(hash table),又稱雜湊表,是根據鍵key直接訪問記憶體儲存位置的資料結構。關鍵字經過雜湊函式,得到鍵key。
給定一對(關鍵字,值),關鍵字經過雜湊函式轉換,得到儲存位置,該儲存位置儲存(關鍵字,值)。
雜湊函式的性質:
如果兩個雜湊值是不相同的(根據同一函式),那麼這兩個雜湊值的原始輸入也是不相同的。
6種雜湊函式:
取關鍵字的某個線性函式值為雜湊位址。即 has
h(k)
=a⋅k
+b
hash(k
)=a⋅
k+b .
假設關鍵字是以r為基的數,並且雜湊表中可能出現的關鍵字都是事先知道的,則可取關鍵字的若干數字組成雜湊位址。
取關鍵字平方後的中間幾位為雜湊位址。
通常在選定雜湊函式時不一定能知道關鍵字的全部情況,取其中的哪幾位也不一定合適,而乙個數平方後的中間幾位數和數的每一位都相關,由此使隨機分布的關鍵字得到的雜湊位址也是隨機的。取的位數由表長決定。
將關鍵字分割成位數相同的幾部分(最後一部分的位數可以不同),然後取這幾部分的疊加和(捨去進製)作為雜湊位址。
選擇一隨機函式,取關鍵字的隨機值作為雜湊位址,通常用於關鍵字長度不同的場合。
取關鍵字被某個不大於雜湊表表長m的數p除后所得的餘數為雜湊位址。即has
h(k)
=kmo
dp,p
≤m
}p} , p\leq m
hash(k
)=km
odp,
p≤m。不僅可以對關鍵字直接取模,也可在摺疊法、平方取中法等運算之後取模。對p的選擇很重要,一般取素數或m,若p選擇不好,容易產生衝突。
介紹三種方法:
h as
hi=(
hash
(key
)+di
)mod
m,i=
1,
2...k(
k≤m−
1)
=(hash(key)+d_)\,}m},
hashi
=(ha
sh(k
ey)+
di)
modm
,i=1
,2..
.k(k
≤m−1
),其中 has
h(ke
y)
hash(k
ey)為雜湊函式, m
m 為雜湊表長, di}
di 為增量序列, i
i i為已發生衝突的次數。
增量序列可以是,線性函式,平方函式,隨機函式的序列。
對雜湊後的衝突值,再次進行雜湊。
關鍵字經過雜湊函式後的值相同,用鍊錶來儲存該記憶體位置的所有值。一般在某個記憶體位置,衝突的值較多時,比如,大於8個,用紅黑樹來儲存。
用python實現乙個簡單的雜湊表,在python中,雜湊表對應的是字典。
整個雜湊表,除留餘數法作為雜湊函式,同時,遇到衝突使用開放定址法解決。同時,動態擴容雜湊表,當儲存的數量達到容量的設定閾值時,進行擴容。
class
dict()
:def
__init__
(self)
: self.capacity =
11 self.load_factor =
0.75
self.size =
0 self.mod = self.capacity
self.hash_table =[(
none
,none
)for i in
range
(self.capacity)
]def
mod_function
(self, x)
:return x%self.mod
defhash
(self,x)
:return self.mod_function(x)
defresize
(self)
: new_capacity =
int(self.capacity*
1.5)
new_hash_table =[(
none
,none
)for _ in
range
(new_capacity)
]for
(key,value)
in self.hash_table:
if key:
hash_k = self.
hash
(key)
if new_hash_table[hash_k][0
]isnone
: new_hash_table[hash_k]
=(key,value)
else
:for i in
range(1
,new_capacity)
: hash_k = self.
hash
(key+i)
if new_hash_table[hash_k][0
]isnone
: new_hash_table[hash_k]
=(key,value)
self.capacity = new_capacity
del self.hash_table
self.hash_table = new_hash_table
defput(self, key, value)
: hash_k = self.
hash
(key)
# 儲存資料與容量比大於載荷因子,擴容
if self.size/self.capacity > self.load_factor:
self.resize(
)# 衝突處理
if self.hash_table[hash_k][0
]isnone
: self.hash_table[hash_k]
=(key,value)
else
:for i in
range
(self.capacity)
: hash_k = self.
hash
(key+i)
if self.hash_table[hash_k][0
]isnone
: self.hash_table[hash_k]
=(key,value)
self.size +=
1def
get(self, key)
: hash_k = self.
hash
(key)
# 判斷是否衝突
h_key, value = self.hash_table[hash_k]
if h_key == key:
return value
else
:for i in
range
(self.capacity)
: hash_k = self.
hash
(key+i)
h_key, value = self.hash_table[hash_k]
if h_key == key:
return value
return-1
dict
= dict(
)for i in
range(11
):dict
.put(i,
"hello{}"
.format
(i))
print
(dict
.capacity)
print
(dict
.get(2)
)
執行結果:
16
hello2
注意: 擴容倍率不是亂定義的,一般選1.5而不是像2這種,這是因為記憶體復用的問題。 如果選用倍率2,已用的內容 1+2+4 + 2**(n-1)… < 2**n;無法復用。 選1.5 就沒有這個問題。
參考:wiki hashtable;
python123 資料結構入門 雜湊表;
知乎 python dict和hashtable的區別;
雜湊表 字典
衝突效能 你在一家雜貨店上班。有顧客來買東西時,你得在乙個本子中查詢 n o n o n 如果本子的內容是按字母順序排列的,可使用二分查詢來找出蘋果的 這需要的時間更短,為o l ogn o log n o logn 前面介紹了兩種用於查詢的資料結構 陣列和鍊錶,為了針對上面的問題,有個更快的查詢方...
雜湊表 字典
1.能夠超快速的檢索效能 2.優化演算法 在不同語言中,雜湊表的叫法不一樣 以 鍵 值對 儲存資料的結構 我們使用雜湊表來儲存鍵值對,假如我們要儲存乙個員工列表,並能夠根據員工編號快速查詢員工,每乙個員工都有唯一的員工編號,我們可以使用這個員工編號作為鍵,使用員工編號的值作為值 現在要在雜湊表中儲存...
C 雜湊表 字典
簡介 雜湊表又稱雜湊表,是根據關鍵碼值 key value 而直接進行訪問的資料結構。用於 因為給定了key value值,用於快速查詢資料。語法 foreach 集合中單個的型別 區域性變數名in 集合物件 foreach 集合中單個的型別 區域性變數名in 集合物件 迴圈過程 總是從開始,一直到...