优先级队列实现说明

时间:2014-01-06 06:29:57

标签: c++ dijkstra

我正在从竞争性编程的书中读到Dijkstra的算法1.在实施程序中,他们写了这样的东西:

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

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

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

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

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

我尝试声明类似的内容:

priority_queue< ii > pq ;

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

任何人都可以告诉我声明的含义:

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

上层声明和

之间有什么区别
priority_queue< ii > pq ;
宣言?

1 个答案:

答案 0 :(得分:4)

因此模板类的声明是这样的:

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

应该有三个模板参数。第一个,&#34; T&#34;,是元素的类型(在您的情况下为ii)。第二个参数是我所谓的&#34;底层容器&#34;。你看,priority_queue是一个适配器,即它秘密使用其他容器,同时向你展示另一组操作。 (您可能希望在维基百科上查找&#34;适配器模式&#34;。)出于性能考虑,您可以告诉编译器它应该在下面使用哪个容器。可以使用标准库中的类dequevector。有关容器类的要求,请参阅here

现在,比较器用于定义元素的排序。它可以是函数指针,也可以是括号运算符重载的类。它需要你的元素类型的两个参数,并返回(bool)&#34; true&#34;如果第一个元素应出现在队列中的第二个元素之后。当您想要更改默认顺序或使用某种奇特的方式来订购元素时,它非常有用。

e.g。请参阅下面的一个简单的例子

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 - 按引擎排量分类的汽车。

当模板参数列表中出现类似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指令告诉预处理器将每个pair<int,int>替换为&#34; ii&#34;,这根本没有帮助。 Typedef告诉编译器&#34; ii&#34;表示pait<int,int>