基于C++11的priority_queue容器适配器的分析

Priority_queue的基本内容

  1. Class priority_queue<>实现出一个 queue,其中的元素依优先级被读取。它的接口和queue 非常相近,亦即push()将会放入一个元素,top()/pop()将会访问/移除下一元素。然而这里所谓“下一元素”并非第一个放入的元素,而是“优先级最高”的元素。

  1. 和往常一样,你可以布通过template 参数指定一个排序准则。默认的排序准则是以operalor<形成降序排列,那么所谓“下一元素”就是“数值最大的元素”。如果同时存在若干个数值最大的元素,我们无法确知究竟哪一个会入选。

  1. Priority_queue 和一般的queue 都定义于头文件<queue>:

#include <queue>
  1. 在头文件<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();}
       ...
   };
}

猜你喜欢

转载自blog.csdn.net/Reol99999/article/details/129422517