关于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