为什么优先级队列需要底层容器中的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。