[英]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上查找“适配器模式”。)出于性能方面的考虑,可以告诉编译器应在下面使用哪个容器。 可以使用标准库中的类, deque
和vector
。 有关容器类的要求,请参见此处 。
现在,比较器是用于定义元素顺序的工具。 它可以是函数指针,也可以是带有括号运算符的类。 它采用您元素类型的两个参数,如果第一个元素应出现在队列中的第二个元素之后,则返回(布尔)“ 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.