雜湊表的實現

2021-08-28 20:25:15 字數 3856 閱讀 3690

簡單來說,雜湊表是一種儲存結構,它儲存的資料是 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 例如存放不同出生年份的人口數量,出生年份是關鍵字,那麼可以用直接定址法。直接定址法的優點是簡單均勻,也不會產生衝突 缺點是該方法適合表比較小...