使用链式哈希实现动态哈希表

时间:2014-01-07 14:56:39

标签: c++ hashtable asymptotic-complexity

我正在尝试使用链式哈希实现动态哈希表(数组中的每个元素都是链表)。 我想知道,复杂性明智,以下哪种可能性更好:  1.当数组已满时,我应该将数组大小加倍,这意味着每个链表至少有一个元素。  2.当我总共有N个元素时(在所有链表中),我应该将数组大小加倍 - 其中N是数组大小。

2 个答案:

答案 0 :(得分:0)

复杂性方面,它们都是一样的。哈希表复杂性以平均情况下的摊销O(1)给出,因为哈希冲突一旦你有一个好的哈希函数,就归结为幸运。无论你做什么,任何哈希表的最坏情况复杂度都是O(N)。

也就是说,有用的实现基于负载因子调整大小,负载因子是总元素和桶数(“数组大小”)之间的比率。等待每个存储桶至少有一个条目将导致次优的行为。但是负载因子为1(N桶中的N个元素)可能太高;我见过的大多数实现默认大约为0.7(10个桶的7个元素),通常让用户配置加载因子(参见C ++和Java)。这是交易内存与速度的关系,哈希表通常都与速度有关。通常,只有分析才能显示任何给定程序的正确值。

此外,尺寸不需要加倍。典型vector实现在每次调整大小时将其大小增加50%或70%,因为对实际应用程序的大规模测试表明,与双倍相比,更好的速度/内存权衡取舍。理所当然,类似的东西将适用于哈希表,尽管这也需要进行分析。

答案 1 :(得分:0)

大量的哈希表实现,包括C ++标准中的几个(unordered_set,unordered_map)。

要回答你的问题,当元素数量达到N时,最好将bin计数(内部数组)加倍。反过来会更难和耗时(找出所有bin是否已满)。

您需要保留一个包含元素数的成员。

您不必担心使用{ return 0;}等错误哈希函数的用户。