我最近一直在考虑HashMaps / Dictionaries,我意识到我对其实现的理解存在差距。
从我的数据结构类中,我被告知哈希值会将键直接映射到链表列表的向量中的位置。根据维基百科,MurmurHash创建了一个32位或128位的值。显然,该值无法直接映射到内存中的某个位置。该哈希值如何用于将基础向量中的位置分配给放置在哈希映射中的对象?
在阅读David Robinson的回答后,我想扩展我的问题: 如果映射是基于列表底层矢量的大小,那么在调整矢量大小时会发生什么?
答案 0 :(得分:2)
通常,当生成散列的结果时,它将通过模N
进行放置,其中N
是链接列表的已分配向量的大小。伪代码:
linked_list = lists[MurmurHash(x) % len(lists)]
linked_list.append(x)
这可以让实施者决定链表的矢量长度(也就是说,他希望在时间效率上交换空间效率的多少),同时保持结果伪随机。
值得一提的常见替代方法是位屏蔽 - 例如,忽略除b
最低有效位之外的所有位。 (例如,执行操作x & 7
忽略除3个最低有效位之外的所有位。这相当于x modulo 2 ^ b,它在大多数操作系统上恰好更快。
回答第二个问题:如果必须调整矢量大小,那么确实需要重新映射存储在字典中的每个值。
implementation of dictionaries in Python上有一篇很棒的博客文章解释了该语言如何实现其内置哈希表(它称之为词典)。在该实施中:
如果使用超过2/3的插槽,字典会调整大小(变大)
广告位列表的大小调整为当前大小的4倍
旧插槽列表中的每个值都会重新映射到新的插槽列表。
该博客文章中描述了许多其他有用的优化;它提供了实现哈希表的实际方面的绝佳视图。