实际编程中利用散列表,请直接用字典即可,本文只是其实现逻辑,大部分的高效是搞明白现有的工具,能够用好
1.第一步元组列表实现映射
class LinearMap:
def __init__(self):
self.items = []
def __len__(self):
return len(self.items)
def add(self,k,v):
self.items.append((k,v))
def get(self,k):
for key ,val in self.items:
if key == k:
return val
raise KeyError
‘’’ 时间代价:add操作是常量时间;get用for循环遍历,时间是线性的 ‘’’
2.改进,速度理论上比LinearMap快100倍
hash() 运算时间是常量,find_map()运行时间是常量,所以linearMap的长度决定了查找时间
class BetterMap:
def __init__(self,n=100):
self.maps = []
for i in range(n):
self.maps.append(LinearMap())
def __len__(self):
l = 0
for i in self.maps:
l += len(i)
return l
def find_map(self,k):
index = hash(k) % len(self.maps)
return self.maps[index]
def add(self,k,v):
m = self.find_map(k)
m.add(k,v)
def get(self,k):
m = self.find_map(k)
return m.get(k)
3.真实列表的实现(让linearMap为固定长度,则查询时间,是固定值)
class HashMap:
def __init__(self):
self.maps = BetterMap(2)
self.num = 0 #记录项数
def get(self,k):
return self.maps.get(k)
def add(self,k,v):
if self.num == len(self.maps.maps):#如果相等,BetterMap中的平均项数为1,重新创建一个大一倍的,重新散列分布
self.resize()
self.maps.add(k,v)
self.num += 1
def resize(self):
new_maps = BetterMap(self.num *2 )
for m in self.maps.maps:
for k , v in m.items:
new_maps.add(k,v)
self.maps = new_maps