簡單來說,雜湊表是一種儲存結構,它儲存的資料是 key:value 型別的。通過空間換時間的方法來加快查詢速度,具體思想是如下:
使用乙個較大的一維陣列儲存value,這個陣列為array
實現乙個雜湊函式,使得hash(key)
的值在上一步的一維陣列下標範圍內
如此,對於任意的key:value,使用hash(key)
,之後就可以知道value在陣列中儲存的下標,訪問速度快過線性查詢array[hash(key)]
由於我們期望,兩個不同的key,hash(key)
之後的結果盡量不相同,這樣才能使得雜湊表儲存空間的利用率提高,另一點,雜湊表的空間換時間的主要原因就是他使用了雜湊函式來確定value在陣列中的下標而非普通的線性查詢。那麼,基於以上兩點,雜湊函式的選取就有以下條件:
由於是無論key的個數有多少,hash(key)
的結果都在乙個有限的集合內,即將乙個無限的集合對映在乙個有限的集合,所以必定會產生不同key但hash(key)
結果一樣的情況,這稱為雜湊碰撞,雜湊表的另一要點就是要解決雜湊碰撞。
解決雜湊碰撞一般有以下方法:
本文主要將2種解決衝突的方法。
鏈位址法
這種方法可以說是最為簡單的,較為容易理解,並且,這種方法無需擔心初始期間開闢的陣列大小不夠,那麼下面具體來講他。
# 包含next屬性的節點
class
mylinkdictentry
:def
__init__
(self)
:# -1:unused 0:dummy 1:active
self.state =-1
self.
hash
=none
self.key =
none
self.value =
none
self.
next
=none
# 雜湊函式
defhash_func
(key,mask)
: hash_val =
0for i in key.encode(
'utf-8'):
hash_val <<
4 hash_val += i
return hash_val % mask
# 基礎字典物件
class
mydictobject
:def
__init__
(self,length=
1024):
# 生成大小為length的陣列來儲存mydictentry
length =
int(length)
self.mask = length # all
self.fill =
0# 0 + 1
self.used =
0# 1
self.data =
[mylinkdictentry(
)for _ in
range
(length)
]def
__str__
(self)
:# 列印字典中的值
s ='' s +=
''return s
# 鏈位址法的字典
class
mylinkdictobject
(mydictobject)
:def
set(self,key, value)
:# 字典增添元素
hash_val = hash_func(key, self.mask)
item = self.data[hash_val]
first_item =
none
while
true
:if item.state ==
1and item.key == key:
# 該節點被使用並且key一致(更新操作)
break
if item.state ==0:
# 該節點偽刪除 記錄第乙個偽刪除的
first_item = item if first_item ==
none
else first_item
if item.state ==-1
:# 該結點未使用,增加
break
if item.
next
: item = item.
next
else
:break
if item.state ==1:
# 更新操作
item.key = key
item.value = value
item.state =
1elif
not item.
next
:# 增加操作
if first_item:
# 增加到第乙個偽刪除節點
item = first_item
item.state =
1 item.key = key
item.value = value
else
:# 增加到最後
if item.state !=-1
: item.
next
= mylinkdictentry(
) item = item.
next
item.state =
1 item.key = key
item.value = value
else
:raise exception(
'未考慮到的情況!'
)def
get(self,key)
:# 字典獲取元素
hash_val = hash_func(key, self.mask)
item = self.data[hash_val]
while item:
if item.state ==
1and item.key == key:
break
else
: item = item.
next
ifnot item:
keyerror(
"沒有這個鍵"
)else
:return item.value
defdelete
(self,key)
:# 字典刪除元素
hash_val = hash_func(key, self.mask)
item = self.data[hash_val]
while item:
if item.state ==
1and item.key == key:
break
else
: item = item.
next
ifnot item:
keyerror(
"沒有這個鍵"
)else
: item.state =
0 self.used -=
1def
__str__
(self)
:# 列印字典中的值
s ='' s +=
''return s
雜湊表(雜湊表)的實現
雜湊函式直接用key size的形式,size為雜湊表的大小。衝突處理採用平方探測法,為保證可以探測到整個雜湊表空間,雜湊表大小設定為4k 3形式的素數。當雜湊表中的元素過多時會造成效能下降,這時應該倍增雜湊表的大小,重新計算原來雜湊表中每個元素在新的雜湊表中的位置。雜湊表的實現 hashtable...
雜湊表 雜湊表 的實現原理
雜湊表可以表述為,是一種可以根據關鍵字快速查詢資料的資料結構。通常情況下,不論雜湊表中資料有多少,增加,刪除,改寫資料的複雜度平均都是o 1 效率非常高。如果說每乙個資料它都對應著乙個固定的位置,那我們查詢特定乙個資料時,就可以直接檢視這個資料對應的位置是否存在資料。乙個形象的例子就是學生在教室中的...
雜湊表(雜湊表) C 實現
雜湊函式就是 關鍵字key 到 值value 的對映 value f key value反映的是關鍵字key的儲存位址。直接定址法 f key a key b 例如存放不同出生年份的人口數量,出生年份是關鍵字,那麼可以用直接定址法。直接定址法的優點是簡單均勻,也不會產生衝突 缺點是該方法適合表比較小...