#源于数据结构与分析的学习#
字典来实现,字典是储存键(key)-值(value)对的数据类型。键用来查找关联的值,这个常常被称作“映射”
字典的键必须是不可变的,例如字符串、数字或元组等,而值可以是任意类型的对象
对于python中的hash Table
映射抽象数据类型定义如下。它是将键和值关联起来的无序集合,其中的键是不重复的,键和值之间一一对应的关系。需要映射支持以下操作。让我们来看看。
1.Map()创建一个空的映射,它返回一个空的映射集合。
2.put(key,val)在映射中加入一个新的键值对。如果键已经存在,就用新值替换旧值。
3.get(key)返回key对应的值。如果key不存在,则返回None
4.del通过del map【key】这样的语句从映射中删除键值对。
5.len()返回映射中储存的键值对的数目
6.in通过key in map这样的语句,在键存在时返回True,否则返回False
这是使用字典来实现hash表,其最大优势是,给定一个键,很快就可以找到其关联的值。
但是我们今天用列表来创建一个hash类,实现映射抽象数据类型。
tips:
slots的列表来储存键(key),而data的列表来存储值。两个列表中的键与值在后面一一对应。
那我们先来看看如何定义一个hash类的初始值
class HashTable: #创建一个hash类
def __init__(self):
self.size = 11
self.slots = [None]*self.size
self.data = [None]*self.size
"""
tips: 1.初始大小可以任意指定,但是选一个素数很关键
在后面的rehash的时候,就不会出现被散列大小整除的现象
2.slots 和 data 用来等效于dic(字典类型)
可以看散列的定义,我们知道初始的时候,每一个槽都是空的
所以这里是设为装有self.size个的[None] 列表
"""
slots 与 data 它们是同步的,到后面我们进行get()和put(),操作的时候就会慢慢的领悟了
上面那句话可以在我们看这些操作时,不断重复,有助于你的理解
“slots的列表来储存键(key),而data的列表来存储值。两个列表中的键与值在后面一一对应。”
好,现在我们来看看其他两大方法
第一个方法:put函数。
但我在此处先写入两个方法,有助于你们的理解
分别是方法1:hashfunction() 和 方法2: rehash()---re有再一次的意义 我们可以理解为 再一次的散列寻找
def function(self,key,size):
return key%size
#用键(大小)除以散列的长度---结果要求余
#得出的结果,便是该键在散列的初始位置
def rehash(self,oldhash,size)
return (oldhash + 1)%size
#这个是再散列,目的是解决冲突,散列更加均匀
def put(self,key,data):
hashvalue = self.hashfunction(key)
#此处求出该数在hash表中的初始位置
if self.slots[hashvalue] == None:
self.slots[hashvalue] = key
self.data[hashvalue] = data
#判断该槽是否为空,若为空,则放入数据
else:
if self.slots[hashvalue] == key:
self.data[hashvalue] = data #替换旧数据
else:
nextslot = self.rehash(hashvalue)#传入旧值
while self.slots[nextslot] != None and\
self.slots[nextslot] != key:
nextslot = rehash(nextslot)
#判断新的节点是否为空或是为对应的键
#直到找到None或是key,才结束循环,然后进行下一步
if self.slots[nextslot] == None:
self.slots[nextslot] = key
self.data[nextslot] = data
else:
self.data[nextslot] = data#替换旧值
这便是put方法
接下来我们来看看get方法,它是如何使用双列表来具体实现的
同理,get函数也先计算初始散列值,就是我在上面写的hashfunction()这个方法,用return返回给函数调用端使用,也就是计算机。如果值不在初始散列值对应的槽中,那么我们会使用rehahs()方法来确定下一个位置。
那么我们先来看看这个函数,更好地来解读以下的code。
def get(self,key):
startslot = self.hashfunction(key)
#获取该键的初始位置,并将其定为开始位置
data = None
stop = False
found = False
position = startslot
#接下要使用while循环进行寻找,顺序查找
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)
if position == startslot:
stop = True
return data
"""
注意:1.while判断条件这样设置的原因是:1.若寻找时,有位置为空,则该元素不存在
2.若该位置的键相等,说明寻找到了,将该处的data返回给用户
3.为确保循环一定能结束,因为不会回到初始槽,如果
遇到初始槽,则说明已经检查完所有的槽,该元素必定不存在。
"""
为了更好让我们来操作hashTable这个类
我们再附上两个方法,来提供额外的字典功能:
def __getitem__(self,key):
return self.get(key)
#说明我们可以通过[]来进行访问
def __setitem__(self,key,data):
return self.put(key,data)
"""
这里我们创建好实例
如:
#1 A = HashTable()
#2 A[54] = "cat" ----已经把这个槽创立好了
#3 print(A[54])
>>> "cat"
以上就是我所的一些操作
"""
还有一部分的方法留到下一期,那么,我们今天对于散列(hashTable)的理解就先到这里
谢谢你的阅读,如有任何疑问,欢迎前来评论区留言