【问题标题】:STL priority_queue<pair> vs. mapSTL priority_queue<pair> 与 map
【发布时间】:2015-01-12 09:00:14
【问题描述】:

我需要一个优先级队列来存储每个键的值,而不仅仅是键。我认为可行的选项是std::multi_map&lt;K,V&gt;,因为它按键顺序迭代,或者std::priority_queue&lt;std::pair&lt;K,V&gt;&gt;,因为它在V 之前按K 排序。除了个人偏好之外,我有什么理由更喜欢其中一个吗?它们真的是一样的吗,还是我错过了什么?

【问题讨论】:

  • std::priority_queue&lt;T&gt; 默认情况下将您的元素存储为 std::vector&lt;T&gt; ,除非您指定不同。它只是容器的适配器,而不是容器本身。
  • @pkrysiak 对。我的意思是使用默认的矢量支持的
  • 然后问题基本上衰减到this one
  • 就我个人而言,我会选择界面最好的那个来完成你想做的事情。
  • @pkrysiak std::priority_queue 与预排序向量不同,因为它允许 O(log N) 插入。不过,如果不需要插入,则更可取。

标签: c++ stl priority-queue


【解决方案1】:

优先级队列最初在 O(N) 时间内排序,然后按降序迭代所有元素需要 O(N log N) 时间。它在幕后存储在std::vector 中,因此在大O 行为之后只有一个很小的系数。不过,其中一部分是在向量内移动元素。如果sizeof (K) 或sizeof (V) 很大,会慢一些。

std::map 是一棵红黑树(在通用实践中),因此插入元素需要 O(N log N) 时间,并在每次插入后保持它们的排序。它们存储为链接节点,因此每个项目都会产生malloc 和free 开销。然后需要 O(N) 时间来迭代它们并破坏结构。

优先级队列总体上应该有更好的性能,但它对你的使用有更大的限制:数据项在迭代过程中会移动,你只能迭代一次。

如果您在迭代时不需要插入新项目,当然可以使用std::sort 和std::vector。这应该比priority_queue 的性能要好一些。

与性能方面的大多数事情一样,唯一确定的判断方法是同时尝试(使用真实世界的测试用例)和测量。

顺便说一句,为了最大限度地提高性能,您可以定义一个自定义比较函数来忽略 V 并仅比较 pair&lt;K,V&gt; 中的 K。

【讨论】:

  • 优先级队列不是按O(n log n)时间排序的,而不是O(n)时间排序的吗?
  • @Iamanon 没有完全排序。形成 PQ 的顺序是 O(n),而按每个顺序删除元素是 O(log n)。
  • @Potatoswatter 我认为插入红黑树是 O(log N)。
  • @RomanByshko O(N log N) 对于所有 N 个元素。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-02-27
  • 2017-05-16
  • 2022-08-03
  • 2011-01-27
  • 1970-01-01
  • 2011-03-24
  • 2021-09-26
相关资源
最近更新 更多