当前位置:   article > 正文

哈希表(hash table)---python实现_python hashtable

python hashtable


哈希表(基本概念)

哈希表(hash table,又称散列表)是一种数据集,其中数据项的存储方式尤其是有利于将来快速的查找定位。

散列表的每一个存储位置,成为槽,可以用来保存数据项,每个槽有一个唯一的名称。
在这里插入图片描述

实现从数据项到存储名称的转换的,称为散列函数(哈希函数)
有一种常见的散列方法是‘求余数’,将数据项厨艺散列表的大小,得到的余数作为槽号。
不过这很明显会存在一个问题,要保存的数据需要存到同一个槽中,会产生冲突。
完美散列函数;给定一组数据项,如果一个散列函数能把每个数据项都映射到不同的槽中,那么这个散列函数就称为‘完美散列函数’。
完美散列函数应用:
数据的一致性校验;(压缩性、易计算性、抗修改性、抗冲突性)
散列函数:
MD5、SHA
python的散列函数库hashlib;自带MD5和SHA系列的散列函数。
包括了md5 / sha1 / sha224 等六种散列函数。

>>> import hashlib
>>> m = hashlib.md5('hello'.encode('utf-8')).hexdigest()
>>> m
'5d41402abc4b2a76b9719d911017c592'
  • 1
  • 2
  • 3
  • 4

散列函数的最酷应用;
区块链技术

冲突解决:数据项链和线性探测

数据项链

我们知道数组的特点是寻址容易,插入和删除数组困难。而链表的特点是寻址困难,插入和删除数据容易。
可以看到哈希表的上面是数组,数组的每个成员包括一个指针,指向一个链表的头节点,当然链表可能为空,也可能链接多个节点。
在这里插入图片描述

我们存储键值对(key-value pair)的方式主要依靠键的特征,通过键的哈希值找到对应的数组下标,然后将其键值对添加到对应的链表中,寻找元素时,也是根据其键的哈希值,找到特定链表其对应的值。

我们可以对比python中的字典,字典是一种可以保存key- value键值对的数据类型,这种键值关联的方法称作‘映射Map’。

  • 关键码具有唯一性
  • 通过关键码可以唯一确定一个数据值

哈希表支持的操作:

  • add(key, val):将key-value关联对加入映射中,如果key已存在,将val替换旧关联值;
  • get(key):给定key,返回关联的数据值,如果不存在,返回None;
  • len( ) 返回映射中key-val键值对的数目;
  • del:通过del hash_map[key] 的语句形式删除key-val关联;
  • in:通过key in hash_map的语句形式,返回key是否存在与关联中,布尔值。

线性探测

开放定址,就是为冲突的数据项再找一个开放的空槽来保存。
向后逐个槽寻找的方法则是开放定址技术中的线性探测。
线性探测法的一个缺点就是聚集的趋势。避免聚集的一种方法就是将线性探测扩展,从逐个探测改为跳跃式探测。

实现Hash_Map

考虑到冲突解决算法,散列表大小应该选择素数。

class Hash_Table(object):
    def __init__(self):
        self.size = 11
        self.slots = [None] * self.size
        self.val = [None] * self.size

    def hash_function(self,key):
        return key % self.size

    def rehash(self,oldhash):
        return (oldhash + 1) % self.size

    def add(self, key, val):
        hash_value = self.hash_function(key)
        if self.slots[hash_value] == None:
            self.slots[hash_value] = key
            self.val[hash_value] = val
        else:
            if self.slots[hash_value] == key:
                self.val[hash_value] = val
            else:
                nextslot = self.rehash(hash_value)
                while self.slots[nextslot] != None and self.slots[nextslot] != key:
                    nextslot = self.rehash(nextslot)
                if self.slots[nextslot] == None:
                    self.slots[nextslot] = key
                    self.val[nextslot] = val
                else:
                    self.data[nextslot] = val

    def get(self, key):
        startslot = self.hash_function(key)
        val = 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
                val = self.val[position]
            else:
                position = self.rehash(position)
                if position == startslot:
                    stop = True
        return val

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

    def __setitem__(self, key, val):
        self.add(key,val)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
from ADT_CLASS import Hash_Table

h = Hash_Table()
h[54] = 'cat'
h[26] = 'dog'
h[93] = 'lion'
h[26] = 'pig'
print(h.slots)
print(h.val)
print(h[26])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
输出:
[None, None, None, None, 26, 93, None, None, None, None, 54]
[None, None, None, None, 'pig', 'lion', None, None, None, None, 'cat']
pig
  • 1
  • 2
  • 3
  • 4
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/神奇cpp/article/detail/812171
推荐阅读
相关标签
  

闽ICP备14008679号