繁体   English   中英

优先队列实现说明

[英]priority queue implementation explanation

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

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

如果我们将整数s作为源,则该实现将按如下所示推对(cost,source)(节点从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是一个适配器,即它在向您提供另一组操作的同时秘密使用了其他容器。 (您可能希望在Wikipedia上查找“适配器模式”。)出于性能方面的考虑,可以告诉编译器应在下面使用哪个容器。 可以使用标准库中的类, dequevector 有关容器类的要求,请参见此处

现在,比较器是用于定义元素顺序的工具。 它可以是函数指针,也可以是带有括号运算符的类。 它采用您元素类型的两个参数,如果第一个元素应出现在队列中的第二个元素之后,则返回(布尔)“ 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;

然后,队列应容纳std::vector vector-满载的汽车(按发动机排量排序)。

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

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

暂无
暂无

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

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