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...