關於hash自己,解決衝突是一個小重點,以下圖。python
—— 定義HashTable類bash
def __init__(self): self.size = 11 self.slots = [None] * self.size self.data = [None] * self.size
注意,因「衝突」而致使的rehash不是本來的"key+1",而是"key的hash結果+1"。用的是」線性解決衝突「的策略。數據結構
def bashfunction(self, key, size): return key%size def rehash(self, oldhash, size): return (oldhash+1)%size
理解的關鍵,有衝突時找下一個位置,app
def put(self, key, data):
hashvalue = self.hashfunction(key, len(self.slots)) if self.slots[hashvalue] == None # 第一次出現,則直接添加 self.slots[hashvalue] = key self.data[hashvalue] = data else: if self.slots[hashvalue] == key: #已經有了則「更新」數值 self.data[hashvalue] = data else:
# 有值但key不是,說明「被佔」了,那就循環直到」沒衝突「時 nextslot = self.rehash(bashvalue, len(self.slots)) while self.slots[nextslot] != None and self.slots[nextslot] != key: # 」被佔「:非空,且key不對 nextslot = self.rehash(nextslot, len(self.slots)) # 找到位置後,看位置的具體狀況; if self.slots[nextslot] == None: # append new key. self.slots[nextslot] = key self.data[nextslot] = data else: # update existing key's value. self.data[nextslot] = data
值得注意的是:」沒找到「的標示是又回到了原來的起始位置。這也是線性探測的特色。spa
def get(self, key):
startslot = self.hashfuncion(key, len(self.slots)) data = None stop = False found = False position = startslot while self.slots[position] != None and not found and not stop: if self.slots[position] == key: found = True data = self.data[position] else: # update 'position', 衝突解決之‘線性探測’ position = self.rehash(position, len(self.slots)) if position == startslot: # 是真沒有這個key stop = True return data
def __getitem__(self, key): return self.get(key) def __setitem__(self, key, data): self.put(key, data)
一個簡單的例子:code
class Tag:
def __init__(self):
self.change={'python':'This is python'}
def __getitem__(self, item):
print('這個方法被調用')
return self.change[item]
a=Tag()
print(a['python'])
End.blog