1.什么是哈希查找
它通过一个哈希函数将待查找的键(Key)映射到存储位置,以实现快速定位数据的目的。哈希查找的核心思想是将数据的存储位置与数据的关键字相关联,从而达到快速查找的目的。时间复杂度为O(1)。
2.(1)哈希表:
哈希表是一种数据结构,可以快速实现插入、查找、删除等操作。通过哈希函数将键映射到表中的一个槽内,以存储与键相应的值(value),注意存储的是键值对。而每个槽都有一个名称,假设为11个槽的哈希表,那么槽的名称为0~10。
(2)哈希函数:
item%len(list),实现从数据到槽名称的一种转换。
3.哈希函数计算方法
(1)取余法
即 将数据除以散列表大小,取其余数作为槽号。
利用h(key) = key%11
4.冲突解决方法
(1)开放寻址法(线性探测法)
假设数据求得的余数为3,而3对应的槽被占用,则寻找后续第一个空槽用于保存键值对。
(2)开放寻址法(跳跃式探测)
线性探测法的一个缺点是有聚集 ,即如果同一个槽冲突的数据项较多的话,这些数据项就会在槽附近聚集起来,从而连锁式影响其它数据项的插入。 避免聚集的一种方法就是将线性探测扩展, 从逐个探测改为跳跃式探测。即每个多个槽进行一次探测,看槽是否为空。
(3)数据项链
散列表中的每个槽就可以容纳多个数据项, 如果有散列冲突发生, 只需要简单地将数据项添加到数据项集合中。
5.代码实现
class Map:
def __init__(self, size=11):
self.size = size
self.slots = [None] * self.size # 存放key
self.date = [None] * self.size # 存放value
def hash_func(self, key, size):
return key % size
def re_hash(self, old_hash, size):
return (old_hash+1) % size
def put(self, key, value):
start_slot = self.hash_func(key, len(self.slots))
if self.slots[start_slot] is None:
""" 没有冲突 """
self.slots[start_slot] = key
self.date[start_slot] = value
else:
""" 存在冲突 """
if self.slots[start_slot] == key:
""" 已存在,而非冲突 """
self.date[start_slot] = value
else:
""" key值冲突,寻找新的key值 """
next_slot = self.re_hash(start_slot, len(self.slots))
while self.slots[next_slot] is not None and self.slots[next_slot] != key:
""" 如果下一个槽非空或者key值不等将一直循环 """
next_slot = self.re_hash(next_slot, len(self.slots))
if next_slot == start_slot:
print("hash表已满")
return
""" 走到这说明找到了一个空槽或者key值相等 """
if self.slots[next_slot] is None:
self.slots[next_slot] = key
self.date[next_slot] = value
else:
self.date[next_slot] = value
def get(self, key):
start_slot = self.hash_func(key, len(self.slots)) # 获取该key%11
date = False
found = False
stop = False
position = start_slot
while self.slots[position] is not None and not found and not stop:
""" 未找到空槽且未找到且未停止就继续循环 """
if self.slots[position] == key:
""" 说明找到了 """
found = True
date = self.date[position]
else:
position = self.re_hash(position, len(self.slots))
if position == start_slot:
""" 说明找了一圈未找到 """
stop = True
return date
def del_date(self, key):
start_slot = self.hash_func(key, len(self.slots))
stop = False
found = False
position = start_slot
while not found and not stop:
""" 未找到且未停止将继续循环 """
if self.slots[position] == key:
self.slots[position] = None
self.date[position] = None
found = True
else:
position = self.re_hash(position, len(self.slots))
if position == start_slot:
stop = True
def len_date(self):
count = 0
for i in self.slots:
if i is not None:
count += 1
return count
def in_date(self, key):
start_slot = self.hash_func(key, len(self.slots))
stop = False
found = False
position = start_slot
while not found and not stop:
if self.slots[position] == key:
found = True
else:
position = self.re_hash(position, len(self.slots))
if position == start_slot:
stop = True
return found
def __getitem__(self, item):
return self.get(item)
def __setitem__(self, key, value):
self.put(key, value)
def __delitem__(self, key):
self.del_date(key)
def __len__(self):
return self.len_date()
def __contains__(self, item):
return self.in_date(item)
h = Map()
h[1] = 'cat'
h[1] = 'dog'
h[2] = 'people'
h[3] = 'people'
h[4] = 'people'
h[5] = 'people'
h[6] = 'people'
h[7] = 'people'
h[8] = 'people'
h[9] = 'people'
h[10] = 'people'
h[11] = 'people'
h[12] = 'people'
B = h.get(1)
A = h.get(2)
print(B)
print(A)
print(2 in h)
print(1 in h)
print(len(h))
print(h.slots)
print(h.date)