问题 为什么哈希表平均具有恒定的访问时间?


我不明白这个解释说明如果n是散列表中的元素数量而m是桶的总数,那么只有当n与theta(n)成比例时,散列表才具有平均的持续访问时间。为什么它必须成比例?


1898
2018-05-04 01:19


起源



答案:


实际上m应该与n成比例。否则你可以,例如,只有一个桶,它就像一个未排序的集。

更确切地说,如果m与n成比例,即m = c * n,那么每个桶中的项目数将是n / m = 1 / c,这是常数。进入任何存储桶是一个O(1)操作(只是计算哈希码),然后通过存储桶的搜索是不变的顺序(你可以只通过存储桶中的项目进行线性搜索,这将是一个常量)。

因此,如果m = c * n,则算法的阶数为O(1)。

举一个相反的例子,假设我们有一个大小为tableSize的固定大小的表。然后每个桶中预期的项目数是n / tableSize,它是n的线性函数。通过存储桶的任何类型的搜索充其量只是一个树的O(log(n))(我假设你没有在存储桶中粘贴另一个哈希表,或者我们在该哈希表上有相同的参数),所以在这种情况下,它不会是O(1)。


10
2018-05-04 01:24



要添加到这个答案,不仅可以获得两个比例,而且当元素的数量时,可以获得恒定的访问时间(n)小于或等于水桶的数量(m)。否则我们就有这样的情况 O(1 + |k|) 其中k是第k个桶中元素的数量。 - David Titarenco
那仍然是不变的访问时间。如果k是常数,则O(1 + | k |)= O(1)。 - Larry Watanabe
如果我们使用开放式寻址来解决冲突,而不是因为几乎每个哈希表的分析都假设链接怎么办?平均恒定访问时间是否仍然保持均匀m与n成正比? - sinoTrinity
@DavidTitarenco,如果 n <= m, 然后 n 仍然是成正比的 m作为 n = cm 哪里 c <= 1。 - Carlos Alegría


答案:


实际上m应该与n成比例。否则你可以,例如,只有一个桶,它就像一个未排序的集。

更确切地说,如果m与n成比例,即m = c * n,那么每个桶中的项目数将是n / m = 1 / c,这是常数。进入任何存储桶是一个O(1)操作(只是计算哈希码),然后通过存储桶的搜索是不变的顺序(你可以只通过存储桶中的项目进行线性搜索,这将是一个常量)。

因此,如果m = c * n,则算法的阶数为O(1)。

举一个相反的例子,假设我们有一个大小为tableSize的固定大小的表。然后每个桶中预期的项目数是n / tableSize,它是n的线性函数。通过存储桶的任何类型的搜索充其量只是一个树的O(log(n))(我假设你没有在存储桶中粘贴另一个哈希表,或者我们在该哈希表上有相同的参数),所以在这种情况下,它不会是O(1)。


10
2018-05-04 01:24



要添加到这个答案,不仅可以获得两个比例,而且当元素的数量时,可以获得恒定的访问时间(n)小于或等于水桶的数量(m)。否则我们就有这样的情况 O(1 + |k|) 其中k是第k个桶中元素的数量。 - David Titarenco
那仍然是不变的访问时间。如果k是常数,则O(1 + | k |)= O(1)。 - Larry Watanabe
如果我们使用开放式寻址来解决冲突,而不是因为几乎每个哈希表的分析都假设链接怎么办?平均恒定访问时间是否仍然保持均匀m与n成正比? - sinoTrinity
@DavidTitarenco,如果 n <= m, 然后 n 仍然是成正比的 m作为 n = cm 哪里 c <= 1。 - Carlos Alegría


严格地说,哈希表访问的平均时间复杂度实际上是Ω(n1/3)。信息的传播速度不能超过光速,这是一个常数。由于空间有三个维度,存储 n 数据位要求某些数据位于n的数量级上1/3 来自CPU。

更多详情 在我的博客中


2
2018-05-04 01:35





碰撞的可能性更高,因此必须扫描具有相同散列密钥的项目列表的发生率也更高。


0
2018-05-04 01:26





访问时间是不变的,因为访问基于哈希值的计算,然后是常量查找以查找适当的桶。假设散列函数在桶之间均匀分配项目,则访问任何单个项目所花费的时间将等于访问其他项目的时间,而不管n。

常数并不一定意味着持续低。平均访问时间与散列函数的均匀分布和桶的数量有关。如果您有数千个项目均匀分布在少量存储桶中,那么您可以快速找到存储桶,然后循环查看存储桶中的大量项目。如果您对项目有很大比例的桶,但是哈希函数错误会将更多项目放在某些桶中而不是其他桶中,则较大桶中项目的访问时间将比其他项目的访问时间慢。


0
2018-05-04 01:28





一个合理大小的哈希表,其中有足够的插槽用于存储的每个元素以及足够的额外空间,将具有散列函数执行大多数工作选择插槽和非常少的冲突,其中不同的元素具有相同的散列。一个非常拥挤的哈希表会有很多冲突,并且会降级为基本上线性搜索,其中几乎每个查找都将是一个具有相同哈希的错误项目,并且您将不得不继续搜索正确的哈希表(哈希表)查找仍然必须在选择第一个插槽后检查密钥,因为它所查找的密钥在存储时可能发生了冲突。

确定命中碰撞比率的确切因素是项目数与散列大小的比率(即,随机选择的时隙将被填充的百分比)。


0
2018-05-04 01:32