写在前面
这一部分学习一下优先级队列这样一种STL容器。priority_ queue 优先级队列是一个拥有权值概念的单向队列queue,在这个队列中,所有元素是按优先级排列的(也可以认为queue是个按进入队列的先后做为优先级的优先级队列——先进入队列的元素优先权要高于后进入队列的元素)。在计算机操作系统中,优先级队列的使用是相当频繁的,进线程调度都会用到。在STL的具体实现中,priority_queue也是以别的容器作为底部结构,再根据堆的处理规则来调整元素之间的位置。
头文件包含
要在程序中使用priority_queue需要包含queue的头文件。
#include <queue>
priority_ queue::priority_queue
构造一个优先级队列,可以直接构造一个空队列或者是现有某基础容器对象的拷贝。参考:priority_queue Class——MSDN,其构造方法一共有七种:
priority_queue();
explicit priority_queue(const Traits&_comp);
priority_queue(const Traits&_comp, const container_type& _Cont);
priority_queue(const priority_queue& right);
template <class InputIterator>
priority_queue(InputIterator first, InputIterator last);
template <class InputIterator>
priority_queue(InputIterator first, InputIterator last, const Traits&_comp);
template <class InputIterator>
priority_queue(InputIterator first, InputIterator last, const Traits&_comp, const container_type& _Cont);
其中,各参数含义如下:
- _ comp:是constTraits的比较函数,用来对队列中的元素进行排列。默认为基本容器的默认排序函数(由小到大);
- _Cont:通过拷贝容器的方式创造队列的那个基本容器。
- right:通过拷贝另一个队列的方式创造一个优先级队列的那个队列。
- first:通过拷贝某一个容器来创建一个优先级队列的容器中的第一个元素。
- last:通过拷贝某一个容器来创建一个优先级队列的容器中的最后一个元素。
具体实例代码可参考:
// The first member function declares priority_queue
// with a default vector base container
priority_queue <int> q1;
// Explicitly declares a priority_queue with nondefault
// deque base container
priority_queue <int, deque <int> > q2;
// The third member function declares a priority_queue
// with a vector base container and specifies that the comparison
// function greater is to be used for ordering elements
priority_queue <int, vector<int>, std::greater<int> > q3;
// The fourth member function declares a priority_queue and
// initializes it with elements copied from another container:
// first, inserting elements into q1, then copying q1 elements into q4
q1.push( 100 );
q1.push( 200 );
priority_queue <int> q4( q1 );
// The fifth member function declares and
// initializes a priority_queue q5 by copying the
// range v5[ first, last) from vector<int> v5 {10,20,30}
priority_queue <int> q5( v5.begin( ), v5.begin( ) + 2 );
// The sixth member function declares a priority_queue q6
// with a comparison function greater and initializes q6
// by copying the range v5[ first, last) from vector v5
priority_queue <int, vector<int>, std::greater<int> > q6( v5.begin( ), v5.begin( ) + 2 );
Member functions
1.empty()
判断优先级队列是否为空。示例代码如下:
// priority_queue::empty
#include <iostream> // std::cout
#include <queue> // std::priority_queue
int main ()
{
std::priority_queue<int> mypq;
int sum (0);
for (int i=1;i<=10;i++) mypq.push(i);
while (!mypq.empty())
{
sum += mypq.top();
mypq.pop();
}
std::cout << "total: " << sum << '\n';
return 0;
}
//Output:
//total: 55
2.size()
返回优先级队列中元素的个数。示例代码如下:
// priority_queue::size
#include <iostream> // std::cout
#include <queue> // std::priority_queue
int main ()
{
std::priority_queue<int> myints;
std::cout << "0. size: " << myints.size() << '\n';
for (int i=0; i<5; i++) myints.push(i);
std::cout << "1. size: " << myints.size() << '\n';
myints.pop();
std::cout << "2. size: " << myints.size() << '\n';
return 0;
}
//Output:
//0. size: 0
//1. size: 5
//2. size: 4
3.top()
获取队列顶层元素。示例代码如下:
// priority_queue::top
#include <iostream> // std::cout
#include <queue> // std::priority_queue
int main ()
{
std::priority_queue<int> mypq;
mypq.push(10);
mypq.push(20);
mypq.push(15);
std::cout << "mypq.top() is now " << mypq.top() << '\n';
return 0;
}
//Output:
//mypq.top() is now 20
4.push()
向队列中插入元素。示例代码如下:
// priority_queue::push/pop
#include <iostream> // std::cout
#include <queue> // std::priority_queue
int main ()
{
std::priority_queue<int> mypq;
mypq.push(30);
mypq.push(100);
mypq.push(25);
mypq.push(40);
std::cout << "Popping out elements...";
while (!mypq.empty())
{
std::cout << ' ' << mypq.top();
mypq.pop();
}
std::cout << '\n';
return 0;
}
//Output:
//Popping out elements... 100 40 30 25
5.pop()
删除队列顶部元素。示例代码如下:
// priority_queue::push/pop
#include <iostream> // std::cout
#include <queue> // std::priority_queue
int main ()
{
std::priority_queue<int> mypq;
mypq.push(30);
mypq.push(100);
mypq.push(25);
mypq.push(40);
std::cout << "Popping out elements...";
while (!mypq.empty())
{
std::cout << ' ' << mypq.top();
mypq.pop();
}
std::cout << '\n';
return 0;
}
//Output:
//Popping out elements... 100 40 30 25
6.emplace()
构造并向队列中插入一个元素。示例代码如下:
// priority_queue::emplace
#include <iostream> // std::cout
#include <queue> // std::priority_queue
#include <string> // std::string
int main ()
{
std::priority_queue<std::string> mypq;
mypq.emplace("orange");
mypq.emplace("strawberry");
mypq.emplace("apple");
mypq.emplace("pear");
std::cout << "mypq contains:";
while (!mypq.empty())
{
std::cout << ' ' << mypq.top();
mypq.pop();
}
std::cout << '\n';
return 0;
}
7.swap()
交换两个队列的内容。示例代码如下:
// priority_queue::swap
#include <iostream> // std::cout
#include <queue> // std::priority_queue
int main ()
{
std::priority_queue<int> foo,bar;
foo.push (15); foo.push(30); foo.push(10);
bar.push (101); bar.push(202);
foo.swap(bar);
std::cout << "size of foo: " << foo.size() << '\n';
std::cout << "size of bar: " << bar.size() << '\n';
return 0;
}
//Output:
//size of foo: 2
//size of bar: 3
VS2008Priority_queue源代码
参考博客:STL系列之五 priority_queue 优先级队列,VS2008中priority_queue源代码如下:
//VS2008中 priority_queue的定义 MoreWindows整理( http://blog.csdn.net/MoreWindows )
template<class _Ty, class _Container = vector<_Ty>, class _Pr = less<typename _Container::value_type> > //默认以vector为容器的
class priority_queue
{ // priority queue implemented with a _Container
public:
typedef _Container container_type;
typedef typename _Container::value_type value_type;
typedef typename _Container::size_type size_type;
typedef typename _Container::reference reference;
typedef typename _Container::const_reference const_reference;
priority_queue() : c(), comp()
{ // construct with empty container, default comparator
}
explicit priority_queue(const _Pr& _Pred) : c(), comp(_Pred)
{ // construct with empty container, specified comparator
}
priority_queue(const _Pr& _Pred, const _Container& _Cont) : c(_Cont), comp(_Pred)
{ // construct by copying specified container, comparator
make_heap(c.begin(), c.end(), comp); //参见《STL系列之四 heap 堆的相关函数》
}
template<class _Iter>
priority_queue(_Iter _First, _Iter _Last) : c(_First, _Last), comp()
{ // construct by copying [_First, _Last), default comparator
make_heap(c.begin(), c.end(), comp);
}
template<class _Iter>
priority_queue(_Iter _First, _Iter _Last, const _Pr& _Pred) : c(_First, _Last), comp(_Pred)
{ // construct by copying [_First, _Last), specified comparator
make_heap(c.begin(), c.end(), comp);
}
template<class _Iter>
priority_queue(_Iter _First, _Iter _Last, const _Pr& _Pred, const _Container& _Cont) : c(_Cont), comp(_Pred)
{ // construct by copying [_First, _Last), container, and comparator
c.insert(c.end(), _First, _Last);
make_heap(c.begin(), c.end(), comp);
}
bool empty() const
{ // test if queue is empty
return (c.empty());
}
size_type size() const
{ // return length of queue
return (c.size());
}
const_reference top() const
{ // return highest-priority element
return (c.front());
}
reference top()
{ // return mutable highest-priority element (retained)
return (c.front());
}
void push(const value_type& _Pred)
{ // insert value in priority order
c.push_back(_Pred);
push_heap(c.begin(), c.end(), comp);
}
void pop()
{ // erase highest-priority element
pop_heap(c.begin(), c.end(), comp);
c.pop_back();
}
protected:
_Container c; // the underlying container
_Pr comp; // the comparator functor
};
此外,参考博客:priority_queue的用法,可以通过堆算法实现类似功能,VS2008中源代码可看做是这个的升级版。代码如下:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
class priority_queue
{
private:
vector<int> data;
public:
void push( int t ){
data.push_back(t);
push_heap( data.begin(), data.end());
}
void pop(){
pop_heap( data.begin(), data.end() );
data.pop_back();
}
int top() { return data.front(); }
int size() { return data.size(); }
bool empty() { return data.empty(); }
};
写在后面
还有queue、stack、heap的用法没有整理。