SGI STL优先队列priority_queue
priority_queue简介
跟普通queue不同的是,priority_queue拥有权值的概念,允许加入新元素、移除旧元素、查看元素值等。priority_queue本身也是一个queue,因此只允许在尾部加入元素,头部取出元素,除此外无法从别的位置存取元素。
普通queue是按先进先出的规则取出元素,内部存储顺序也是按进入先后顺序排列;priority_queue并非如此排列,而是自动按元素的权值排列。权值最高值,排在最前面。
默认情况,priority_queue用一个max-heap实现,而priority_queue是以vector作为底部容器表现的complete binary tree(完全二叉树)。因为max-heap可以满足priority_queue所需的“依赖权值高低自动排序”的特性。
priority_queue数据结构
类似于stack、queue,priority_queue也是以底部容器完成操作的,加上heap处理规则。因此,STL中priority_queue往往不被归类为container(容器),而被归类为container adapter(容器适配器)。
# define __STL_DEPENDENT_DEFAULT_TMPL(_Tp) = _Tp
// 优先队列
template <class _Tp,
class _Sequence __STL_DEPENDENT_DEFAULT_TMPL(vector<_Tp>),
class _Compare
__STL_DEPENDENT_DEFAULT_TMPL(less<typename _Sequence::value_type>) >
class priority_queue {
public:
// 内嵌类型定义
typedef typename _Sequence::value_type value_type;
typedef typename _Sequence::size_type size_type;
typedef _Sequence container_type;
typedef typename _Sequence::reference reference;
typedef typename _Sequence::const_reference const_reference;
protected:
_Sequence c; // 底层容器
_Compare comp; // 比较子, 元素大小比较标准
public:
priority_queue() : c() {}
explicit priority_queue(const _Compare& __x) : c(), comp(__x) {}
// 以下任意构造函数都立刻于底层容器内产生一个implicit representation heap
// 因为调用了make_heap
priority_queue(const _Compare& __x, const _Sequence& __s)
: c(__s), comp(__x)
{ make_heap(c.begin(), c.end(), comp); }
priority_queue(const value_type* __first, const value_type* __last)
: c(__first, __last) { make_heap(c.begin(), c.end(), comp); }
priority_queue(const value_type* __first, const value_type* __last,
const _Compare& __x)
: c(__first, __last), comp(__x)
{ make_heap(c.begin(), c.end(), comp); }
priority_queue(const value_type* __first, const value_type* __last,
const _Compare& __x, const _Sequence& __c)
: c(__c), comp(__x)
{
c.insert(c.end(), __first, __last);
make_heap(c.begin(), c.end(), comp);
}
bool empty() const { return c.empty(); }
size_type size() const { return c.size(); }
const_reference top() const { return c.front(); }
void push(const value_type& __x) {
__STL_TRY {
// push_heap 是泛型算法, 先利用底层容器的push_back()将新元素
// 推入末端, 再重排heap
c.push_back(__x);
push_heap(c.begin(), c.end(), comp); // 泛型算法
}
__STL_UNWIND(c.clear()); // commit or clear all
}
void pop() {
__STL_TRY {
// pop_heap 是泛型算法, 从heap内取出一个元素. 不是真正将元素弹出, 而是重排heap,
// 然后再以底层容器的pop_back() 取得被弹出的元素.
pop_heap(c.begin(), c.end(), comp);
c.pop_back();
}
__STL_UNWIND(c.clear()); // commit or clear all
}
};
# define __STL_TRY try
# define __STL_CATCH_ALL catch(...)
# define __STL_THROW(x) throw x
# define __STL_RETHROW throw
# define __STL_NOTHROW throw()
# define __STL_UNWIND(action) catch(...) { action; throw; }
priority_queue测试实例
#include <queue>
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
{ // test case1: test priority_queue
int ia[9] = { 0,1,2,3,4,8,9,3,5 };
priority_queue<int> ipq{ ia, ia + 9 };
cout << "size = " << ipq.size() << endl; // size = 9
for (size_t i = 0; i < ipq.size(); i++) {
cout << ipq.top() << ' '; // 9 9 9 9 9 9 9 9 9
}
cout << endl;
while (!ipq.empty()) {
cout << ipq.top() << ' '; // 9 8 5 4 3 3 2 1 0
ipq.pop();
}
cout << endl;
}
return 0;
}