unordered_map 的最坏情况是啥?
Posted
技术标签:
【中文标题】unordered_map 的最坏情况是啥?【英文标题】:What is the worst case scenario for an unordered_map?unordered_map 的最坏情况是什么? 【发布时间】:2014-08-01 01:00:36 【问题描述】:我发现了很多关于map
和unordered_map
复杂性的帖子。据说unordered_map
的最坏情况复杂度为O(N)
。出于我的目的,我将输入作为排序值,如1 2 5 6 9 11 12..
。我需要插入或查找并删除一个值。我将不得不经常进行插入/删除。我想过使用set
,它在所有情况下都具有 log(n) 复杂性。然后我偶然发现了具有最佳 O(1) 复杂度的 unordered_map。但是我需要了解在我的场景中我会面临 unordered_map 的最坏情况吗?会是怎样的情景?
编辑:在我的情况下,所有值都是唯一的。
【问题讨论】:
你有输入的整数范围吗? 是的,最多 2^29。 数据结构没有时间复杂度,算法有。 您可能会发现this link 很有趣 - 它讨论了由创建将触发哈希表中最坏情况行为的输入键引起的拒绝服务攻击。 【参考方案1】:unordered_map
最坏的情况通常发生在哈希函数为映射中的每个插入产生冲突时。
我说“通常”是因为标准只指定了最坏情况的复杂性,而不是何时或如何发生,所以理论上你的问题的答案是它是实现定义的。
由于您的所有值都是唯一的,并且显然是整数(它提供了非常好的散列,可能是最佳的 _ 这又取决于实现),您不会遇到这种最坏的情况。插入/查找/删除将是 O(1),所以它看起来是一个合理的选择。
【讨论】:
“当散列函数产生冲突时” - 这听起来像是孤立的散列函数......要学究起来,这是当散列函数映射到桶上(例如,可能是% bucket_count()
,尽管我不认为这是强制性的)有碰撞。例如,如果哈希函数产生的不同值是 bucket_count()
的倍数,它们可能会发生冲突。
嗯,是的,这就是我的意思,你将如何制定它?【参考方案2】:
根据散列算法的实现,使用 unordered_map 时,有序数据集最终可能会导致大量冲突。由于您的数据是有序的,因此使用树集可能更有利。(假设您不想添加重复数据。)
【讨论】:
你指的是哪个操作对于平衡树来说最坏的情况是 O(n)?不插入、删除或查找,这些都是 O(log n) 最坏的情况。 一棵平衡良好的树,将为您提供平均 O(log n) 的删除、插入和查找案例复杂度;最坏的情况仍然是 n。但是,大多数时间操作将是 O(log n)。 @Benjamin Lindley 根据树集的实现方式,它可能有 o(n) 时间。(例如 bst)*bigocheatsheet.com @ByteByter 平衡树实现,例如 RB 树或 AVL 树,保证是 O(log n) 最坏情况。你的链接是这样说的。 @Benjamin Lindley 同意,我只是说根据数据结构的编码方式,情况可能会更糟。 @ByteByter:只有当它的编码方式不再满足它声称的数据结构的定义时。但在这种情况下,它可能比 O(n) 差得多。它可能是 O(n^2) 或 O(2^n)。但那时我们不会称它为平衡二叉树,因为它不能满足一棵树的性能要求。请注意,您所指的 bst,即我假设的链接中的那个,是一棵非平衡树。以上是关于unordered_map 的最坏情况是啥?的主要内容,如果未能解决你的问题,请参考以下文章
在不使用 if 的情况下插入/更新 std::unordered_map 元素的最快方法是啥?