Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 何时调整哈希表的大小?_Algorithm_Hashtable - Fatal编程技术网

Algorithm 何时调整哈希表的大小?

Algorithm 何时调整哈希表的大小?,algorithm,hashtable,Algorithm,Hashtable,在各种哈希表实现中,我看到了可变哈希表何时应该调整大小(增长)的“神奇数字”。通常,这个数字在每个分配的插槽添加值的65%到80%之间。我假设,一个更高的数字会带来更多碰撞的可能性,而一个更低的数字则会以使用更多内存为代价 我的问题是这个数字是如何得出的? 这是武断的吗?基于测试?基于其他一些逻辑?据我所知,这个数字是基于经验测试的启发式 如果散列值分布合理,那么神奇的负载因子(如您所说)通常在70%左右。较小的负载系数意味着您在浪费空间,而没有真正的好处;更高的加载因子意味着您将使用更少的空间

在各种哈希表实现中,我看到了可变哈希表何时应该调整大小(增长)的“神奇数字”。通常,这个数字在每个分配的插槽添加值的65%到80%之间。我假设,一个更高的数字会带来更多碰撞的可能性,而一个更低的数字则会以使用更多内存为代价

我的问题是这个数字是如何得出的?


这是武断的吗?基于测试?基于其他一些逻辑?

据我所知,这个数字是基于经验测试的启发式

如果散列值分布合理,那么神奇的负载因子(如您所说)通常在70%左右。较小的负载系数意味着您在浪费空间,而没有真正的好处;更高的加载因子意味着您将使用更少的空间,但会花费更多的时间处理哈希冲突


(当然,如果您知道散列值是完全分布的,那么您的负载因子可以是100%,并且您仍然不会浪费空间,也不会发生散列冲突。)

这取决于键。如果您知道您的散列函数对于所有可能的键都是完美的(例如,使用),那么您就知道只有很少的冲突,所以这个数字更高

但大多数时候,你对按键了解不多,只知道它们是文本。在这种情况下,您必须猜测,因为您甚至没有测试数据来提前了解哈希函数的行为

所以你希望一切顺利。如果你的散列函数对键来说是非常糟糕的,那么你将会有很多冲突,并且永远不会达到增长点。在这种情况下,选择的数字是不相关的

如果您的哈希函数足够,那么它应该只创建少量冲突(小于50%),因此65%到80%之间的数字似乎是合理的


也就是说:除非您的哈希表必须是完美的(=巨大的大小或大量的访问),否则不要麻烦。例如,如果您有十个元素,那么考虑这些问题是浪费时间。

冲突高度依赖于数据和使用的哈希函数


大多数数字都基于启发式或哈希值正态分布的假设。(大约70%的AFAIK值是可扩展散列表的典型值,但人们总是可以构造这样的数据流,从而得到更多/更少的冲突)

猜测一下,大多数人至少从一本书(例如,Knuth,第3卷)中的数字开始,这些数字是通过测试生成的。视情况而定,一些人可能会在事后进行测试,并做出相应的调整——但据我所见,这些人可能是少数

正如我在a中所概述的,“正确”的数字也在很大程度上取决于解决碰撞的方式。不管是好是坏,这一事实似乎被广泛忽视——人们通常不会选择特别适合他们使用的碰撞解决方案的数字


OTOH,我在测试中发现的另一点是,它很少有很大的不同。你可以在相当大的范围内选择数字,并获得相当相似的总体速度。最重要的是要小心避免把数字推高,特别是如果你使用类似于线性探测的碰撞解决方案。

< P>我认为你不想考虑表的“满”(总共桶中有多少个桶有值)。而是为一个新项目找到一个位置可能需要的碰撞次数

几年前我读过一本编译书(不记得书名或作者),书中建议只使用链表,直到你有超过10到12个条目。这似乎支持10次以上的碰撞,这意味着需要时间重新调整大小

建议平均哈希链长度为5(在该算法中,平均冲突数)足以触发重新哈希。似乎有测试支持,但我不确定我读的论文是否正确


看起来调整大小的条件主要是测试的结果。

调整大小如何减少冲突的数量?较长数组的哈希函数仍然相同,因此相同密钥仍会发生冲突,对吗?@Core_Dumped-是,哈希函数保持不变,表中项的哈希值保持不变。但是存储桶的长度会发生变化,因此存储桶项目所在的位置也会发生变化。调整大小意味着更改存储桶数组(通常)的长度,然后重新存储哈希表中的所有项。每个铲斗链的平均长度下降,这意味着碰撞更少。