Python拉鍊法和開位址法實現字典

2022-04-28 16:00:10 字數 2417 閱讀 6795

python字典(dictionary)是除列表之外python中最靈活的內建資料結構型別。列表是有序的物件結合,字典是無序的物件集合。兩者之間的區別在於:字典當中的元素是通過鍵來訪問的,而不是通過偏移訪問。

在列表中使用下標索引可以快速的得到對應的值,那麼我們需要做的有兩件事情:

怎樣把鍵計算出乙個唯一值

因為字典的鍵是不可變的,可hash的,因此我們可以用hash函式計算key對應的唯一hash值。

怎樣把這個唯一值均勻並且唯一的分布在長度固定的列表中

hash雜湊是可以把大資料集對映到定長資料集的演算法,因此我們可以對上述計算出來的hash值進行雜湊。很明顯雜湊之後會出現雜湊衝突。因此我們需要處理這種衝突一遍唯一值能夠均勻唯一的分布。這個時候就有兩種處理雜湊衝突的方法:拉鍊法和開位址法

把具有相同雜湊位址的k,v對放在同乙個單鏈表中。下面實現兩個函式

還可以實現更多的函式,比如dict.keys()

#!/usr/bin/env python

# coding=utf-8

slots =

slotsnum = 32

for _ in range(32):

def put(slots, key, value):

i = hash(key) % slotsnum

pos = -1

for pos, (k, v) in enumerate(slots[i]):

if key == k:

break

else:

if pos >= 0 and pos < len(slots[i]):

slots[i][pos] = (key, value)

def get(slots, key):

i = hash(key) % slotsnum

for k, v in slots[i]:

if key == k:

return v

else:

raise keyerror(key) # 不存在時丟擲異常

put(slots, 'a', 1)

print(get(slots, 'a'))

put(slots, 'b' ,2)

print(get(slots, 'b'))

put(slots, 'a', 3)

print(get(slots, 'a'))

下面將這兩個函式封裝成類

class dict:

def __init__(self, num):

self.__solts__ =

self.num = num

for _ in range(num):

def put(self, key, value):

i = hash(key) % self.num

for p, (k, v) in enumerate(self.__solts__[i]):

if k == key:

break

else:

return

self.__solts__[i][p] = (key, value)

def get(self, key):

i = hash(key) % self.num

for k, v in self.__solts__[i]:

if k == key:

return v

raise keyerror(key)

# keys函式

def keys(self):

ret =

for solt in self.__solts__:

for k, _ in solt:

return ret

封裝成類之後,使用方法和python提供的dict就比較像了

python字典內部實現時處理雜湊衝突的方法就是開位址法,開位址法在後續補充

記得幫我點讚哦!

念念不忘,必有迴響,小夥伴們幫我點個贊吧,非常感謝。

我是職場亮哥,yy高階軟體工程師、四年工作經驗,拒絕鹹魚爭當龍頭的斜槓程式設計師。

聽我說,進步多,程式人生一把梭

雜湊函式之衝突處理之開位址法

開位址法 基本思想 當關鍵碼key的雜湊位址h0 hash key 出現衝突時,以h0為基礎,產生另乙個雜湊位址h1 如果h1仍然衝突,再以h0 為基礎,產生另乙個雜湊位址h2 直到找出乙個不衝突的雜湊位址hi 將相應元素存入其中。這種方法有乙個通用的再雜湊函 數形式 其中h0 為hash key ...

資料結構 雜湊中開放位址法與拉鍊法對比

1 拉鍊法處理衝突簡單,且無堆積現象,即非同義詞決不會發生衝突,因此平均查詢長度較短 2 由於拉鍊法中各煉表上的結點空間是動態申請的,故它更適合於造表前無法確定表長的情況 3 開放定址法為減少衝突,要求裝填因子 較小,故當結點規模較大時會浪費很多空間。而拉鍊法中可取 1,且結點較大時,拉鍊法中增加的...

約瑟夫問題(迴圈鍊錶法和公式法)python版

n個人站在乙個等待被處決的圈子裡。第乙個人從1開始報數,報m的將被殺掉,下乙個人接著從1開始報。如此反覆,最後剩下乙個人就是最後的勝利者。輸入 n,m。其中n為總人數,依次編號為0,1 n,m為被處決的報數數值。輸出 最後活下來人的編號。用迴圈單鏈表去模擬這個過程。n個人看做n個鍊錶節點,節點1的v...