优先级队列实现说明

priority queue implementation explanation

本文关键字:说明 实现 队列 优先级      更新时间:2023-10-16

我在读《竞争编程1》一书中Dijkstra的算法。在实现程序中,他们写了这样的东西:

#define pair<int,int> ii;
priority_queue< ii,vector<ii>,greater<ii> > pq ;

如果我们将整数s作为源,则实现显示如下推送对(成本,源)(节点编号从1到n):

pq.push(ii(0,s)) ;

我的问题是,我们正在优先级队列中推送一对成本和节点。但是,priority_queue声明中的另外两个参数(即vector和greater)在做什么呢?

priority_queue< ii,vector<ii>,greater<ii> > pq ;

我试着声明这样的东西:

priority_queue< ii > pq ;

代码是有效的(在我尝试过的那些测试用例上)。

有人能告诉我他们所说的声明是什么意思吗:

priority_queue< ii,vector<ii>,greater<ii> > pq ;

上限申报和之间有什么区别

priority_queue< ii > pq ;

声明?

所以模板类的声明是这样的:

template <class T, class Container = vector<T>, class Compare = less<typename Container::value_type> > class priority_queue;

应该有三个模板参数。第一个,"T",是元素的类型(在您的情况下为ii)。第二个参数是我所说的"底层容器"。您可以看到,priority_queue是一个适配器,即它秘密地使用其他容器,同时向您呈现另一组操作。(您可能想在维基百科上查找"适配器模式"。)出于性能考虑,您可以告诉编译器它应该在下面使用什么容器。可以使用标准库中的类dequevector。有关容器类的要求,请参见此处。

现在,比较器是用来定义元素顺序的东西。它可以是函数指针,也可以是重载了括号运算符的类。它接受元素类型的两个参数,如果第一个元素出现在队列中的第二个元素之后,则返回(bool)"true"。当您想要更改默认顺序,或者使用一些奇特的方式对元素进行排序时,它非常有用。

例如,参见下面的一个简单示例

struct car{
car(double engine_displ):_engine_displ(engine_displ) {} 
double _engine_displ;
};
bool cmp_cars(car one, car other){
return one._engine_displ < other._engine_displ;
}
//..somewhere else
std::priority_queue<car, std::vector<car>, cmp_cars> pq;

然后队列应该容纳按发动机排量排序的车辆的CCD_ 4。

当模板参数列表中有类似class Container = vector<T>的内容时,当您没有说明底层容器类型时,编译器会为您填充std::vector<T>。这就是为什么您可以只说priority_queue<ii>;编译器将其扩展到CCD_ 8。在您的示例中,本书的作者明确使用greater<ii>,因此队列应该将最少的元素放在前面。这是有道理的,因为在Dijkstra的算法中,你对成本最低的路径感兴趣。默认情况下,priority_queue<ii>使用less<ii>,所以现在队列会将具有最大cose的路径放在前面,这没有意义。

附带说明一下,您可能会发现代码实际上是typedef pair<int,int> ii#define指令告诉预处理器用"ii"替换每个pair<int,int>,这根本没有帮助。Typedef告诉编译器"ii"的意思是pait<int,int>