python中的散列表

自定义散列表

class HashTable(object):
    # 用两个列表来实现映射的数据结构类型。其中一个称为slots(槽),用来存储key,另一个称为data,用来存储数据值。
    def __init__(self):
        self.size = 11                                      #槽数
        self.slots = [None] * self.size                     #利用列表实现一个散列表,每一个元素都被初始化为None。
        self.data = [None] * self.size                        #初始化散列表槽为None

    # 向映射中添加一个新的密钥-数据值对。如果密钥已存在,则将旧数据值替换为新的。
    def put(self, key, data):
        hashvalue = self.hashfunction(key, len(self.slots))    #获取散列值作为索引
        if self.slots[hashvalue] == None:                    #若该索引位置为空,则
            self.slots[hashvalue] = key                     #在该索引位置放入key及data
            self.data[hashvalue] = data
        else:                                                #若该索引位置不为空,则
            if self.slots[hashvalue] == key:                #若该索引位置已存在的key值与待处理key值相同,则
                self.data[hashvalue] = data                 #将旧数据值替换为新数据
            else:                                            #若该索引位置已存在的key值与待处理key值不同,则
                nextslot = self.rehash(hashvalue, len(self.slots))    #线性探测下一个槽
                # 若下一个槽的索引位置不为空,并且已存在的key值与待处理key值不同,则
                while self.slots[nextslot] != None and self.slots[nextslot] != key:
                    nextslot = self.rehash(nextslot, len(self.slots))    #继续探测下一个空槽
                if self.slots[nextslot] == None:            #若下一个槽的索引位置为空,则
                    self.slots[nextslot]= key                 #在该索引位置放入key及data
                    self.data[nextslot] = data
                else:                                        #若下一个槽的索引位置已存在的key值与待处理key值相同,则
                    self.data[nextslot] = data                 #将旧数据值替换为新数据
    
    # 散列函数,获取散列值作为索引
    def hashfunction(self, key, size):
        # 求余,将要存储的数据项与散列表的大小相除,返回余数作为这个数据项的散列值
        return key % size 
    
    # 再散列函数,线性探测向后搜索每一个槽,直到遇到第一个空槽。
    def rehash(self, oldhash, size):
        return (oldhash + 1) % size                         #求余

    # 根据给定的key值,返回关联的数据,若不存在,返回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:                    #若找到对应key,则
                found = True
                data = self.data[position]                     #获取对应data
            else:                                            #若没找到对应key,则
                position = self.rehash(position, len(self.slots))    #线性探测下一个槽
                if position == startslot:                    #若依次向下查找一遍后,又循环查找到初始槽,则
                    stop = True                             #停止查找,已全部查找了,说明没有这个key。
        return data
    
    # 运算符__getitem__和__setitem__允许使用“[]”对字典进行访问。这表示一旦一个散列表被建立,我们所熟悉的索引操作符都将是可用的。
    def __getitem__(self, key):
        return self.get(key) 

    def __setitem__(self, key, data):
        self.put(key, data)

if __name__ == '__main__':
    ha = HashTable()                                        #实例化散列表类
    ha.put(0, 'haha')                                        #put()添加数据
    print(ha.get(0))                                        #get()获取
    print(ha[0])                                            #__getitem__()获取
    ha[1] = 'hehe'                                            #__setitem__()设置
    print(ha.slots)                                            #存储key的list
    print(ha.data)                                            #存储data的list
--------------------- 
作者:夜空下的凝视 
来源:CSDN 
原文:https://blog.csdn.net/qq_38882327/article/details/89328415 
版权声明:本文为博主原创文章,转载请附上博文链接!

 

posted @ 2019-07-12 09:36  海予心  阅读(675)  评论(0编辑  收藏  举报