我有一个应用程序(C ++),我认为STL priority_queue
可以很好地服务。 The documentation说:
Priority_queue是一个容器适配器,意味着它是在某个底层容器类型之上实现的。默认情况下,底层类型是vector,但可以显式选择其他类型。
和
优先级队列是一个标准概念,可以通过多种不同方式实现;这个实现使用堆。
我之前假设 top()
是O(1)
,而push()
将是O(logn)
(我选择{{}}的两个原因首先是{1}} - 但文档既没有证实也没有否定这种假设。
深入挖掘,序列概念的文档说:
单元素插入和擦除的复杂性依赖于序列。
priority_queue
使用priority_queue
(默认情况下)作为堆,其中:
...支持对元素的随机访问,最后元素的恒定时间插入和删除,以及在开头或中间插入和删除元素的线性时间。
我推断,使用默认vector
,priority_queue
为top()
,O(1)
为push()
。
问题1:这是对的吗? (O(n)
访问权限为top()
,O(1)
为push()
?)
问题2:如果我使用O(n)
(或O(logn)
)代替push()
,我是否能够set
效率multiset
一个vector
用于实施priority_queue
?这样做的后果是什么?结果会有哪些其他行动受到影响?
N.B。:我担心时间效率,而不是空间。
答案 0 :(得分:33)
优先级队列适配器使用标准库堆算法来构建和访问队列 - 这是您应该在文档中查找的那些算法的复杂性。
top()操作显然是O(1)但可能你想在调用它之后pop()堆(根据Josuttis)是O(2 * log(N))和push( )是O(log(N)) - 相同的来源。
从C ++标准,25.6.3.1,push_heap:
复杂性:至多是log(last-first)比较。
和pop_heap:
复杂性:最多2 * log(最后 - 第一)比较。
答案 1 :(得分:5)
没有。这是不正确的。 top()是O(1),push()是O(log n)。阅读文档中的注释2,看看此适配器不允许迭代向量。 Neil对于pop()是正确的,但是这仍然允许在O(log n)时间内使用堆进行插入和删除。
答案 2 :(得分:5)
top()
- O(1) - 因为它只返回元素@ front。
push()
-
push_into_heap - 最多是log(n)比较。 O(logn)时间
所以push()的复杂性是 - LOG(n)的
答案 3 :(得分:2)
如果底层数据结构是堆,top()将是常量时间,push(EDIT:和pop)将是对数的(就像你说的那样)。向量仅用于存储以下内容:
HEAP:
1
2个3
8 12 11 9
VECTOR(用于存储)
1 2 3 8 12 11 9
您可以将其视为我孩子的位置元素是(2i)和(2i + 1)
他们使用向量,因为它按顺序存储数据(这比离散更有效且缓存友好)
无论它是如何存储的,都应该始终实现堆(尤其是制作STD lib的众神),以便pop是常量而push是对数的
答案 4 :(得分:2)
C ++ STL priority_queue底层数据结构是Heap数据结构(Heap是一个非线性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).
答案 5 :(得分:1)
问题1:我没有使用vector
(或deque
顺便说一句)查看标准,但AFAIK,O(1)
的复杂度为top()
,{ {1}}和O(log n)
{1}}。我曾经将push()
与我自己的堆与pop()
std::priority_queue
以及O(1)
和push()
top()
进行了比较,它肯定没有O(log n)
那么慢{1}}。
Q2:pop()
不能用作O(n)
的基础容器(不是序列),但是可以使用set来实现set
{{1的优先级队列}和priority_queue
。但是,这可能不会超过O(log n)
实施push()
。