【发布时间】:2020-11-11 00:13:38
【问题描述】:
与键关联的索引通常在最简单的哈希表实现中通过以下方式检索:
size++;
int hash = hashcode(key);
int index = hash % size;
对于任意键,我们可以说索引将是[0, size - 1] 范围内的整数,每个结果的概率相等。下表描述了添加 N 个元素后前 5 个索引的这些概率。
Index | 0 1 2 3 4
--------------------------------------------------------------------------------------------
Probabilities | 1
| 1/2 1/2
| 1/3 1/3 1/3
| 1/4 1/4 1/4 1/4
| 1/5 1/5 1/5 1/5 1/5
| ...
| 1/N 1/N 1/N 1/N 1/N
____________________________________________________________________________________________
Total | H(N) H(N) - 1 H(N) - 1.5 H(N) - 1.83 H(N) - 2.08
H(N) 描述了应该在索引 0 的链中收集多少元素。之后的每个链在统计上应该有更少的元素。
H(N) 也是直到并包括第 N 项的谐波级数的值。虽然没有广义的封闭形式来描述调和级数,但可以使用以下公式非常准确地近似该值,
H(N) ≈ ln(N) + 0.5772156649 + 1 / (2N) - 1 / (12N^2)
“近似”部分可以归因于ln(N) + 0.5772156649之后的术语。 ln(N) 是最大的函数,因此摊销时间复杂度应该是O(log n)。
我有什么遗漏吗?非常感谢您在这里澄清。
【问题讨论】:
-
这个计算肯定需要至少两个数字:你要存储的元素的数量,以及哈希表中的桶数。桶的数量越多,链的预期长度就越短。公式中的桶数在哪里?
-
这能回答你的问题吗? Is a Java hashmap search really O(1)?
-
您还错过了可以随时调整哈希表大小以确保仅采用一小部分索引(并随后减少每个索引处的链接)的事实
-
说“算法 X 具有复杂性 Y”是模棱两可的。存在(至少)三种复杂性:最坏情况、预期情况和最佳情况。典型哈希表的最坏情况获取(即所有键具有相同的哈希)是 O(n)。最好的情况通常是 O(1)(即所有键都有不同的散列)。预期情况取决于预期的散列分布和相对于 n 的桶数。无限桶将给出 O(1),而 1 个桶将给出 O(n)。您假设桶数为 n+1 的假设对于该算法来说并不典型。
-
@khelwood 在这个非常简单的实现中,桶的数量是
size。
标签: java data-structures time-complexity hashtable amortized-analysis