Priority_queue的基本内容
Class priority_queue<>实现出一个 queue,其中的元素依优先级被读取。它的接口和queue 非常相近,亦即push()将会放入一个元素,top()/pop()将会访问/移除下一元素。然而这里所谓“下一元素”并非第一个放入的元素,而是“优先级最高”的元素。
和往常一样,你可以布通过template 参数指定一个排序准则。默认的排序准则是以operalor<形成降序排列,那么所谓“下一元素”就是“数值最大的元素”。如果同时存在若干个数值最大的元素,我们无法确知究竟哪一个会入选。
Priority_queue 和一般的queue 都定义于头文件<queue>:
#include <queue>
在头文件<queue>中,class priority_queue定义如下:
namespace std {
template <typename T,typename Container = vector<T>,
typename Compare = less<typename Container::value_type>>
class priority_queue;
第一个template参数是元素类型,带有默认值的第二个template 参数定义了priority queue内部用来存放元素的容器。默认容器是vector。带有默认值的第三个template 参数定义出“用以查找下一个最高优先级元素”的排序准则,默认以operator<作为比较标准。
实际上priority_queue 只是很单纯地把各项操作转化为内部容器的对应调用。你可以使用任何 sequence 容器支持 priority_queue,只要它们支持Random-access iterator 和front()、push_back()、pop_back()等操作就行。由于 priority queue需要用到STL heap算法,所以其内部容器必须支持random access。例如你可以使用deque来容纳元素:
std::priority_queue<float,std::deque<float>> pbuffer;
如果要定义自己的排序准则,就必须传递一个函数或function object,用以比较两个元素并以此作为排序准则。
例如,以下式子定义了一个反向排序(降序)的priority queue;
std::priority_queue<float,std::vector<float>,std::greater<float>> pbuffer;
在此priority queue中,“下一个元素”始终是元素值最小者。
核心接口
Priority_queue 的核心接口主要由成员函数 push(),top()和pop()组成:
push ():将一个元素放人priority queue中。
pop():从priority queue内移除一个元素。
top():返回priority queue内的“下一个元素。
注意,如果priority queue 内没有元素,执行top()和pop()会得致不确定的行为。你可以调用成员函数size()和empty()检验容器是否为空。
细究Class priority_queue<>
Priority_queue 使用STL的heap算法:
namespace std{
template <typename T, typename Container = vector<T>,typename Compare = less<typename Container::value_type>>
class priority_queue{
protected:
Compare comp;
Container c;
public:
explicit priority_queue(const Compare& cmp = Compare(),const Container& cont = Container()):comp(cmp),c(cont) {
make_heap(c.begin(),c.end(),comp);}
void push(const value_type& x) {c.push_back(x);push_heap(c.begin(),c.end(),comp);}
void pop(){pop_heap(c.begin(),c.end(),comp);c.pop_back();}
bool empty() const { return c.empty();}
size_type size() const { return c.size();}
const value_type& top() const { return c.front();}
...
};
}