映射抽象数据类型实现Python

2020-10-23 11:34发布

映射抽象数据类型是散列的应用之一,因为其散列函数与存储空间的关联,使得查找效率大大提高,但随之而来的是空间利用率的下降。准确的说是一种空间换时间。

其实字典也是映射抽象数据类型,因为映射函数的关系,使得存储的数据是无序的。我就简单实现了一下,包括put方法,get方法和dels方法,有了增删改查,其他方法的就简单多了。

因为要存储键和值,而又要用到散列,所以散列肯定是和键key有关,对其计算散列值,并将其存储。那么值value怎么存储呢,因为key和value是有关系的,我们可以用相同的散列值来存储,根据key计算出散列值后,也准备另一个表,在同样的散列值的下标处,存储value。

前面提到,由于表的长度的原因,线性探测再散列解决冲突的时候可能会造成循环检测固定的位置(比如线性加5的时候,而表的长度是10,那么就会一直是两个固定的位置,从而永远也散列不到其他的位置),(尽管我用到的加1的线性探测,但是为了避免循环检测固定的位置),还是将表的长度设为质数。

# 散列映射数据结构

class HashTable(object):

    # 初始化,两个列表,一个表用于存储key,一个表用于存储实际数据vlaue
    def __init__(self):
        self.size = 11
        self.slots = [None] * self.size
        self.data = [None] * self.size

    # 哈希函数,计算哈希值,利用求余法
    def hash_function(self, key):
        return key % self.size

    # 冲突解决函数,发生冲突后就线性探测再散列,看是否为空,为空则占用。
    # 注意要求余,因为末尾到首部要求余才能回去。
    def rehash(self, oldhash):
        return (oldhash + 1) % self.size

    # 添加函数
    # 两个作用,如果存在这个key,那就是修改data
    # 如果不存在,则是为了存储
    def put(self, key, data):
        hash_value = self.hash_function(key)

        # 看看对应的哈希值的位置是否已经占用,若为空,则将key和value分别存储
        if self.slots[hash_value] == None:
            self.slots[hash_value] = key
            self.data[hash_value] = data

        # 不为空的话,可能就是已经存了这个key(也就是要修改data),也可能是被别的占用了(冲突)
        else:
            # 修改data
            if self.slots[hash_value] == key:
                self.data[hash_value] = data

            # 造成冲突
            else:
                # 持续计算下一个hash值,直到找到。
                next_slot = self.rehash(hash_value)
                while self.slots[next_slot] != None and self.slots[next_slot] != key:
                    next_slot = self.rehash(next_slot)

                # 找到了可以存储的位置
                if self.slots[next_slot] == None:
                    self.slots[next_slot] = key
                    self.data[next_slot] = data

                # 找到了可以替换的位置(修改)
                else:
                    self.data[next_slot] = data


    # 获取data函数
    def get(self, key):
        
        start_slot = self.hash_function(key)

        data = None
        stop = False
        found = False
        position = start_slot

        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

    def dels(self, key):
        start_slot = self.hash_function(key)

        data = None
        stop = False
        found = False
        position = start_slot

        while self.slots[position] != None and not found and not stop:
            # 找到
            if self.slots[position] == key:
                found = True
                self.slots[position] = None
                self.data[position] = None
            else:
                # 未找到,再散列
                position = self.rehash(position)

                # 循环一圈还未找到,那就是没有保存这个数据
                if position == startslot:
                    stop = True
        return found
    

        
    def __get_item__(self, key):
        return self.get(key)

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



H = HashTable()

H.put(1, '张三')
H.put(2, '李四')
H.put(3, '王五')

print(H.get(54))
print(H.get(1))

print(H.put(54, '王二麻子'))
print(H.get(54))

H.dels(54)
print(H.get(54))



作者:qq_42907161

链接:https://blog.csdn.net/qq_42907161/article/details/108414937

来源:CSDN
著作权归作者所有,转载请联系作者获得授权,切勿私自转载。