繁体   English   中英

STL priority_queue的效率

[英]Efficiency of the STL priority_queue

我有一个应用程序(C ++),我认为STL priority_queue可以很好地为其提供服务。 该文件说:

Priority_queue是一个容器适配器,这意味着它是在某些基础容器类型之上实现的。 默认情况下,基础类型是向量,但是可以显式选择其他类型。

优先级队列是一个标准概念,可以通过许多不同的方式实现。 此实现使用堆。

我以前曾假设 top()O(1) ,而push()将是O(logn) (我首先选择priority_queue的两个原因)-但是文档既没有确认也没有否认这一假设。

深入研究,Sequence概念的文档说:

单元素插入和擦除的复杂性取决于序列。

priority_queue使用vector (默认情况下)作为堆,该vector

...支持随机访问元素,在元素的末尾进行恒定时间插入和删除,以及在元素的开始或中间进行线性时间插入和去除元素。

我推断,使用默认的priority_queuetop()O(1)push()O(n)

问题1:正确吗? top()访问是O(1)push()O(n)吗?)

问题2:如果我使用set (或multiset )而不是vector来实现priority_queue我是否可以在push()上实现O(logn)效率? 这样做的后果是什么? 结果还有哪些其他操作?

注意:我担心这里的时间效率,而不是空间。

优先级队列适配器使用标准库堆算法来构建和访问队列-这是您应该在文档中查找的那些算法的复杂性。

top()操作显然是O(1),但大概是您想在调用它之后弹出()堆(根据Josuttis )是O(2 * log(N)),而push()是O(log(N ))-相同的来源。

从C ++ Standard 25.6.3.1开始,push_heap:

复杂度:最多进行对数(最后-先)比较。

和pop_heap:

复杂度:最多2个* log(最后-最先)比较。

top() -O(1)-因为它只返回元素@ front。

push() -

  • 插入向量-0(1)摊销
  • push_into_heap-最多进行log(n)个比较。 O(登录)

    所以push()的复杂度是-log(n)

不,这是不正确的。 top()为O(1),push()为O(log n)。 阅读文档中的注释2,以查看此适配器不允许迭代向量。 Neil关于pop()是正确的,但是仍然允许使用堆在O(log n)时间内进行插入和删除。

C ++ STL priority_queue底层数据结构是堆数据结构(堆是一种非线性ADT,它基于完整的二叉树,而完整的二叉树通过vector(或Array)容器实现。

ex  Input data : 5 9 3 10 12 4.

Heap (Considering Min heap) would be :

                   [3]
             [9]             [4]
         [10]    [12]     [5]


   NOW , we store this min heap in to vector,             
      [3][9][4][10][12][5].
      Using formula ,
      Parent : ceiling of n-1/2
      Left Child : 2n+1
      Right Child : 2n+2 .
  Hence ,
    Time Complexity for 
             Top = O(1) , get element from root node.
             POP()= O(logn) , During deletion of root node ,there  is      chance to violation of  heap order . hence restructure of heap order takes at most O(logn) time (an element might move down to height of tree).
            PUSH()= O(logn) , During insertion also , there might chance to violation of  heap order . hence restructure of heap order takes at most O(logn) time (an element might move up to root from leaf node).

如果基础数据结构是堆,则top()将是恒定时间,而push(编辑:和pop)将是对数的(就像您说的那样)。 向量仅用于存储以下内容:

堆:
1个
2 3
8 12 11 9

矢量(用于存储)

1 2 3 8 12 11 9

您可以将其视为位置我的孩子的元素是(2i)和(2i + 1)

他们使用向量是因为它顺序存储数据(与离散数据相比,效率更高且对缓存更友好)

无论如何存储,都应始终执行堆(尤其是制作STD库的神灵),以便pop恒定且push是对数的

Q1:我没有看标准,但是AFAIK使用vector (或deque btw)时, top()的复杂度为O(1) O(log n)push()pop()的复杂度为O(log n) pop() 我曾经将std::priority_queue与我自己的带有O(1) push()top()以及O(log n) pop()的堆进行了比较,但它的速度肯定不如O(n)慢。

Q2: set不能用作priority_queue (不是Sequence)的基础容器,但是可以使用set来通过O(log n) push()pop()实现优先级队列。 但是,这可能不会超过std::vector实现的std::priority_queue

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM