哈希表问题

时间:2011-03-19 03:45:19

标签: hashtable

当面试官问我哈希表有什么缺点时。他告诉我哈希表从初始化中占用了大量空间。这意味着,我们需要为哈希表(bucket)预先分配内存。即使我们实际上并不需要那么多内存,我们也没有那么多条目。

这是否合理?

因为我检查了维基百科,没有在文章中讨论这个缺点。

谢谢!

2 个答案:

答案 0 :(得分:3)

这取决于实施。实现哈希表的一种方法是使初始表不那么大,如果加载因子(已使用元素与可用时隙的比率)增加超过阈值,则增加表大小(有几种方法可以做到这一点,所有细节都在wikipedia article you discussed)。

你提到的情况肯定是可能的,因为有些条件(初始表大小很大,插入的元素很少),但很可能是数据结构选择不佳的结果。

答案 1 :(得分:3)

根据您实现哈希表的方式以及最初有多少个桶,可能是一个合理的缺点。散列表需要大约一半(或更多)的桶是空的,否则碰撞变得更加可能。所有的桶最初都是空的,但是在将项添加到哈希表之后,大多数实现都会扩展桶的数量,因此至少有一半是免费的。这意味着您有O(n)个空桶。这是否重要取决于您拥有多少物品以及铲斗有多大。如果存储桶是结构体,它们可能会非常大,因为它们需要沿着指向键和值的指针存储哈希值(如果不是实际的键和值)。更常见的是,存储桶是指向存储散列的容器的指针以及指向键和值的指针。然后每个桶的大小取决于指针的大小。这几乎总是32位或64位(除非您使用的是嵌入式处理器)。

因此,假设每个桶有4个字节的最佳情况,您最终将使用4兆字节的内存用于具有500,000个对象的哈希表(请记住:大约一半的桶是空的)。另外,这五十万个使用过的桶中的每一个都有一个节点,其中包含指向实际数据的指针。这将使用每个值另外12个字节(尽管有内存对齐约束,它更像是16个字节)。那将是另外8MB,不包括任何实际数据!

另一方面,大多数数据结构都有很大的内存开销。二叉搜索树每个节点有四个指针(一个用于键,一个用于值,两个用于子节点)。在32位系统上每个节点16个字节,这与哈希表的数量相当(至少在一个数量级内)。

如果您要存储的只是字符,那么与实际数据相比,任何这些数据结构的开销都可能很大,但在实践中,除非使用巨大的数据集并且可怕地处理这些数据集,否则它不应该太大问题低效的哈希表实现。