具有伪随机散列方法的散列数组的大小

时间:2013-05-24 22:26:31

标签: c data-structures hash

我对设置散列数组的良好且有效的大小感到困惑。我正在阅读的这本书说,负载系数应该在75%左右才能成为一个好的散列阵列。但在实际尝试测试散列数组放置键之前,我不知道如何在理论上决定数组的大小。达到最佳散列阵列大小是否有任何线索或重要提示?并且大小取决于您用于散列的方法吗?

2 个答案:

答案 0 :(得分:1)

您的哈希表解决方案依赖于事先知道要放入表中的元素数量。相反,动态增长和萎缩是最好的。

建议使用小的哈希表大小(< = 1)进行初始化,并在加载因子达到150-200%时将哈希表大小翻两番。这涉及将整个旧表重新散列为一个新表,但在现实生活中不应经常发生。

还应该有缩小阈值,大约是增长阈值的1/2。

通过使增长和缩小阈值彼此远离,如果您在临界大小周围添加/删除哈希表元素,则会阻止大量工作。

哈希表大小有一个额外的好处是它们是素数。典型的散列函数包含一些预哈希函数,比如说unsigned Hash(unsigned item)然后使用哈希表大小修改结果:BucketIndex = Hash(item)%HashTableSize如果Hash()不做,则主要哈希表大小会改善分散很好。

对于素数值,我建议在Hash数据结构中保留HashPrime_Index,然后在需要知道哈希表的大小时使用下表。

static const size_t HashPrime[] = { 0, 2, 3, 7, 13, 31, 61, ... }; // Primes just less than powers of 2.

成长时,使用0,3,13 ......当收缩时使用......,61,13,2。

当您使用主哈希表大小时,最佳哈希表大小更少取决于方法Hash()。注意:Hash()应返回一个大整数。

答案 1 :(得分:0)

随着元素数量的增长,您可以重新散列哈希表。此过程会更改存储桶的数量。根据细节,这甚至可能是必要

  • 如果你使用链接(即具有相同散列值的所有元素都进入同一个桶),那么理论上你可以无限制地增长表而不需要重新散列,但它最终基本上只是一个链表(或任何序列)容器代表一个桶)。因此,您应该跟踪当前的负载因子(元素数量除以桶数),并在表格过大时增大表格。

  • 如果你使用探测(“开放寻址”),那么一旦探测无法为新元素找到一个空闲点,你就重新进行