python实现哈希表

哈希表的概念

哈希函数:一个把查找表中的关键字映射成该关键字对应的地址的函数,即为Hash(key)=Addr
哈希表:是根据关键字而直接进行访问的数据结构。也就是说,哈希表建立了关键字和存储地址之间的一种直接映射关系。

哈希表的实现

  1. 如果为空,就直接插入。
  2. 插入数据时,解决冲突的办法:
    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

  • 5
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值