字典和哈希表空间复杂度
Posted
技术标签:
【中文标题】字典和哈希表空间复杂度【英文标题】:Dictionaries and Hashtables space complexity [duplicate] 【发布时间】:2016-11-03 12:08:14 【问题描述】:我对字典和哈希表有些困惑,我想澄清一下。假设我有当前字典和当前 python 运行的哈希的当前输出。
Dict = dict()
print(hash('a'))
print(hash('b'))
print(hash('c'))
Dict['a'] = 1
Dict['b'] = 2
Dict['c'] = 3
print(Dict)
有输出
1714333803
1519074822
1245896149
'a': 1, 'c': 3, 'b': 2
所以据我所知,哈希表只是一个数组,其中哈希是哈希表的索引。例如,“a”的哈希值为 1714333803,因此我的哈希表索引 1714333803 的值为“a”。所以我很困惑哈希表有多少索引以及哈希函数如何产生答案?它是否使用模数并具有固定范围的索引?因为字典的给定打印输出'a': 1, 'c': 3, 'b': 2
,但是假设即使它输出,字典实际上是一个至少有 1714333803 个索引的数组是否正确,因为包含 3 个元素并且更不用说包含多少太浪费空间了。同样对于哈希表,索引中没有值的内容是什么,null?
【问题讨论】:
您可以动态调整数组的大小。但是,它必须重新计算每个键的哈希值。这个链接看起来很有趣laurentluce.com/posts/python-dictionary-implementation “没有价值的索引,null”是什么意思?没有哈希的键?或者数组中没有被填充的位置? 也可以观看此视频:youtube.com/watch?v=C4Kc8xzcA68 【参考方案1】:dict
的实际大小取决于实现,但在您的情况下,它可能是 8。那么,这是如何工作的?
dict
(或一般的哈希映射)的工作原理是为每个键计算一个数字哈希。例如,就您而言,这是hash("a") == 1714333803
。现在,哈希不直接用作索引。相反,它被映射到字典的大小。
一种简单的方法是取模 (%
)。假设您的 dict
大小为 8。然后hash("a") % 8 == 1714333803 % 8 == 3
。所以你的项目实际上是在第 4 位。通过构造查找算法,任何项目都不能在数组之外有索引。
这里有一些更复杂的事情,比如哈希冲突。例如,如果另一个项目具有哈希 98499
,则 也 映射到 3
。在这种情况下,有一些冲突解决策略会选择不同的索引。他们大多尝试均匀地大步走阵列。
那么,为什么您的 dict
的大小为 8?因为那是default size in python。一旦你的dict
太小,就必须调整它的大小。与数组相比,这是在dict
实际满之前完成的——即two thirds filling。这样做是为了减少哈希冲突 - 如果您的 dict
已满 99%,则实际上可以保证发生冲突。对于大小为 8 的字典,您必须在调整大小之前输入 5-6 个项目,即 doubles its capacity 到 16。
注意CPython 3.6+ 和PyPy (for a long time) 使用two-stage data structure 表示dict
。第一阶段是哈希表,但第二阶段不是。这将键映射(第一阶段)和数据存储(第二阶段)分开。稀疏的第一阶段为紧凑的第二阶段提供索引:
# based on Raymond Hettingers mail on python-dev
# the key mapping, using a hashtable
# indices[hash(key) % length] => data index
indices = [None, None, None, 0, None, 2, 1, None]
# the data storage, packed in insertion order
# entries[index] => hash(key), key, value
entries = [[1714333803, 'a', 1],
[1519074822, 'b', 2],
[1245896149, 'c', 3]]
该方案在查找算法上更复杂(由于间接),但对于迭代(直接在数据存储上)和内存效率更高。只有索引表是稀疏的,需要超大。除非项目被删除,否则数据存储空间与需要一样大。
【讨论】:
确实,如果我理解正确的话,我认为它是使用按位实现的:hash(key) & of (size - 1)
,实际上是取“最后”三位(如果大小 == 8)。以上是关于字典和哈希表空间复杂度的主要内容,如果未能解决你的问题,请参考以下文章