为什么优先级队列需要底层容器中的front()、pop_back()而不是back()、pop_back()? 从C++引物中也知道,
优先级队列需要随机访问 除了正面、后推和后推操作 我也从谷歌上读到这篇文章,知道:为什么优先级队列需要底层容器中的front()、pop_back()而不是back()、pop_back()? 从C++引物中也知道,,c++,C++,优先级队列需要随机访问 除了正面、后推和后推操作 我也从谷歌上读到这篇文章,知道: 推送:向队列中添加新元素 pop:删除队列中最大的元素 top:访问队列中最大的元素 push应该通过push_back实现,没有问题。 和pop和top似乎在同一个元素上运行。一个是访问它,另一个是删除它。所以我认为这两个操作应该通过pop\u front()和front()或pop\u back()和back()来实现 所以我很困惑,为什么要求front()和pop_back() 例如,让我们假设底层容器
- 推送:向队列中添加新元素
- pop:删除队列中最大的元素
- top:访问队列中最大的元素
push
应该通过push_back
实现,没有问题。
和pop
和top
似乎在同一个元素上运行。一个是访问它,另一个是删除它。所以我认为这两个操作应该通过pop\u front()
和front()
或pop\u back()
和back()
来实现
所以我很困惑,为什么要求front()
和pop_back()
例如,让我们假设底层容器是一个向量
,并且包含一些int元素,比如1,2,3,4,5,6
。适配器接口“pop()
,top()
”如何与底层“front()
,pop\u back()
”一起工作?尽管priority\u队列上的pop()
最终删除了顶层元素,但它必须保持不变,如果所有元素都简单地切换过来,就不会发生这种情况。因此,它通过将顶部值从front()
交换到back()
和pop\u back()
来工作,然后将替换的值与其子项之一交换,直到恢复不变量
类似地,push()
调用push_back()
,然后执行一系列交换,尽管是在另一个方向
注意:由于C++使用最大堆(与常规约定相反),不变的是任何元素都必须大于其子元素(如果它们存在)。因为大多数有用的问题都涉及最小堆,所以几乎总是必须指定
std::greater
作为Compare
模板参数。@Someprogrammerdude我无法理解优先级队列接口和(底层容器)最小操作要求之间的关系。我的意思是,为什么最不需要的是push_back
,pop_back
和front
。(push_back
当然很容易理解)pop
用于删除top
元素。所以我认为底层操作也应该针对相同的元素,对吗?假设vector
、pop_back()
和front()
不针对同一个元素。我认为这是因为优先级队列实现是通过堆进行的。对不起,我对希普知之甚少(ಥ_ಥ). 据我所知,你是这样说的:例如,我将1,2,3
存储在一个p队列中(使用vector
)。经过一些排序后,它内部看起来像[3][2][1]。当我调用pop
,它变成[1][2][3](将顶部值调回),然后弹出[3],是这样吗?一般来说,插入1,2,3
后的顺序是3,1,2
。这是因为插入2
后,通过向上移动2
来恢复不变量(我称之为“涓流向上”,类似于下面描述的“涓流向下”):2,1
。然后,插入3
,让它慢慢地流出来,所以2,1
→ <代码>2、1、3
→ <代码>3,1,2(交换2
和3
)。在删除时,正如@o11c所说,您交换front()
和back()
,执行弹出返回()
,然后让新的front()
,“滴流”,因此3,1,2
→ <代码>2、1、3→ 2,1
(完成后,2
无需滴下,因为它已经>超过了它的(唯一)子级)。@Rick顺便说一句,你可能想看看和的描述。pq的push()
可以实现为c。push_back()
然后是push_heap()
。pq的pop()
可以实现为pop\u heap()
,然后是pop\u back()
。还有make\u heap()
,在从迭代器范围创建pq时非常有用(或者initializer\u list
,如果有这样的构造函数)–首先通过从范围复制来创建容器,然后make\u heap()
@ArneVogel您的详细解释非常有帮助。我读过一些关于heap的文章。结合答案和您的评论,我现在对它有了模糊的理解。谢谢:D。