哈希表的概念
哈希函数:一个把查找表中的关键字映射成该关键字对应的地址的函数,即为Hash(key)=Addr
。
哈希表:是根据关键字而直接进行访问的数据结构。也就是说,哈希表建立了关键字和存储地址之间的一种直接映射关系。
哈希表的实现
- 如果为空,就直接插入。
- 插入数据时,解决冲突的办法:
1. 如果key相等,且在key所对应的位置上已有数据,就进行替换;
2.如果key不相等,就利用线性探测法,往后找一个位置,直到找到空的位置,再填入
假设哈希表长度为11,分别用两个列表来保存关键字和数据。
代码中的print()
函数是为了方便理解,才加上的,可以删除
# 实现hashtable,指定在key位置存入data
class HashTable:
def __init__(self):
self.size=11
self.slots=[None]*self.size # hold the key items
self.data=[None]*self.size # hold the data values
def hashfunction(self,key,size):
return key%size
def rehash(self,oldhash,size):
return (oldhash+1)%size
def put(self,key,data):
hashvalue=self.hashfunction(key,len(self.slots))
if self.slots[hashvalue]==None: # 如果slot内是empty,就存进去
self.slots[hashvalue]=key
self.data[hashvalue]=data
else: # slot内已有key
if self.slots[hashvalue]==key: # 如果已有值等于key,更新data
self.data[hashvalue]=data # replace
else: # 如果slot不等于key,找下一个为None的地方
nextslot=self.rehash(hashvalue,len(self.slots))
while self.slots[nextslot]!=None and self.slots[nextslot]!=key:
nextslot=self.rehash(nextslot,len(self.slots))
print('while nextslot:',nextslot)
if self.slots[nextslot]==None:
self.slots[nextslot]=key
self.data[nextslot]=data
print('slots None')
else:
self.data[nextslot]=data
print('slots not None')
def get(self,key):
startslot=self.hashfunction(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:
position=self.rehash(position,len(self.slots))
if position==startslot:
stop=True
return data
def __getitem__(self,key):
return self.get(key)
def __setitem__(self,key,data):
print('key:',key)
print('data:',data)
self.put(key,data)
程序运行
1
H=HashTable()
H[54]='cat'
此时,54%11=10
,满足条件self.slots[hashvalue]==None
key: 54
data: cat
[None, None, None, None, None, None, None, None, None, None, 54]
[None, None, None, None, None, None, None, None, None, None, 'cat']
2
H=HashTable()
H[54]='cat'
H[54]='kat'
此时,54%11=10
,不满足条件self.slots[hashvalue]==None
,但满足self.slots[hashvalue]==key
,所以在相应位置进行数据的替换
key: 54
data: cat
key: 54
data: kat
[None, None, None, None, None, None, None, None, None, None, 54]
[None, None, None, None, None, None, None, None, None, None, 'kat']
3
H=HashTable()
H[54]='cat'
H[54]='kat'
H[65]='mat'
此时,65%11=10
,既不满足条件self.slots[hashvalue]==None
,也不满足self.slots[hashvalue]==key
,所以要进行线性探测,查看下一个位置(第0个位置)是否为空,因为下一个位置为空,也就是self.slots[nextslot]==None
,所以不进行while
循环
key: 54
data: cat
key: 54
data: kat
key: 65
data: mat
slots None
[65, None, None, None, None, None, None, None, None, None, 54]
['mat', None, None, None, None, None, None, None, None, None, 'kat']
4
H=HashTable()
H[54]='cat'
H[54]='kat'
H[65]='mat'
H[76]='rat'
此时,既不满足条件self.slots[hashvalue]==None
,也不满足self.slots[hashvalue]==key
,所以要进行线性探测,探测到的下一个位置(65所在的位置)不为空,所以进入while
循环,找到下下一个位置(第1个位置)为空,于是填入
key: 54
data: cat
key: 54
data: kat
key: 65
data: mat
slots None
key: 76
data: rat
while nextslot: 1
slots None
[65, 76, None, None, None, None, None, None, None, None, 54]
['mat', 'rat', None, None, None, None, None, None, None, None, 'kat']
5
H=HashTable()
H[54]='cat'
H[54]='kat'
H[65]='mat'
H[76]='rat'
H[77]='tat'
此时,既不满足条件self.slots[hashvalue]==None
,也不满足self.slots[hashvalue]==key
,所以要进行线性探测,探测到的下一个位置(65所在的位置)不为空,所以进入while
循环,找到下下一个位置(76所在的位置)不为空,而下下下一个位置(第2个位置)为空,于是填入
key: 54
data: cat
key: 54
data: kat
key: 65
data: mat
slots None
key: 76
data: rat
while nextslot: 1
slots None
key: 77
data: tat
while nextslot: 2
slots None
[65, 76, 77, None, None, None, None, None, None, None, 54]
['mat', 'rat', 'tat', None, None, None, None, None, None, None,
6
H=HashTable()
H[54]='cat'
H[54]='kat'
H[65]='mat'
H[76]='rat'
H[77]='tat'
此时,和上一步一样,但是,因为77已经存在,所以进行的是数据的替换
key: 54
data: cat
key: 54
data: kat
key: 65
data: mat
slots None
key: 76
data: rat
while nextslot: 1
slots None
key: 77
data: tat
while nextslot: 2
slots None
key: 77
data: pat
while nextslot: 2
slots not None
[65, 76, 77, None, None, None, None, None, None, None, 54]
['mat', 'rat', 'pat', None, None, None, None, None, None, None, 'kat']
参考:
https://runestone.academy/runestone/static/pythonds/SortSearch/Hashing.html