对于大多数操作,哈希表的摊销性能通常被认为是O(1)。
标准LinkedList实现的搜索操作的摊销性能是多少?是O(n)吗?
我对如何计算这一点感到困惑,因为在最坏的情况下(假设总是碰撞的哈希函数),哈希表在搜索操作方面几乎等同于LinkedList(假设标准存储桶实现。)
我知道在实践中,除非哈希函数被破坏,否则这种情况永远不会发生,因此,由于冲突很少,因此平均性能几乎是一系列操作的恒定时间。但是在计算摊销的最坏情况时,我们不应该考虑最坏情况下的最坏情况序列吗?
答案 0 :(得分:5)
没有"摊销最坏情况的表现"。摊销表现是一种平均的"在很长的一系列操作中表现。
使用哈希表时,有时需要在长序列插入后调整哈希表的大小,这将花费O(n)时间。但是,由于它只发生在每个O(n)插入中,因此该操作的成本分散在所有插入上以获得O(1)摊销时间。
是的,在最糟糕的哈希函数中,每个操作的哈希表可能是O(n)。但是,分析这样的哈希表是没有意义的,因为它不会成为典型用法的情况。
答案 1 :(得分:2)
“最坏情况”有时取决于“在什么约束条件下的最坏情况”。
具有有效但是愚蠢的散列函数的散列表的情况通常不是一个有意义的“最坏情况”,它不是很有趣。因此,您可以在最小的假设下分析哈希表的平均性能(实际上)哈希函数在所有哈希值集合中均匀地分配所有密钥的集合。
如果散列函数声音合理但不具有加密安全性,则需要考虑单独的“最坏情况”。恶意或不知情的用户可以系统地提供哈希冲突的数据。对于“最坏情况输入”与“假设输入分布均匀的哈希”的最坏情况,你会得到一个不同的答案。
在给定哈希表的给定序列中,其中一个可能会引发重新哈希。然后你会认为那个特定的“最坏情况”。这与整体输入数据几乎没有关系 - 如果负载因子足够高,你最终会重新发送 ,但很少。这就是为什么“摊销”运行时间是一个有趣的衡量标准,每当你能够在n
次操作的总成本上设置一个更紧密的上限,而不仅仅是n
次上一次操作的最紧密上限。
即使哈希函数在加密方面是安全的,但是你可以获得哈希全部冲突的输入的可能性微乎其微。这是“对所有可能的输入进行平均”和“对最坏情况输入的一系列操作进行平均”之间存在差异的地方。所以“摊销”这个词也带有小字。根据我的经验,它通常意味着一系列操作的平均值,以及数据是好还是坏的问题是不摊销的一部分。 nneonneo说“没有最坏情况下的最坏情况表现”,但根据我的经验,肯定存在最坏情况下的摊销表现。因此,这是值得精确的,因为这可能反映出我们每个人都期望该术语的差异。
当哈希表提出O(1)
分期付款时,它们意味着n
次插入需要O(n)
次,或者(a)假设哈希函数没有发生任何病态上的错误或(b)假设随机输入的n
插入的预期时间。因为无论哪种方式你都得到相同的哈希表答案,所以你很想说你正在谈论哪一个。