【C++-STL 队列与优先队列用法详解】
1、队列queue
queue 模板类的定义在
与stack 模板类很相似,queue 模板类也需要两个模板参数,一个是元素类型,一个容器类
型,元素类型是必要的,容器类型是可选的,默认为deque 类型。
定义queue 对象的示例代码如下:
queue
queue
queue 的基本操作有:
入队,如例:q.push(x); 将x 接到队列的末端。
出队,如例:q.pop(); 弹出队列的第一个元素,注意,并不会返回被弹出元素的值。
访问队首元素,如例:q.front(),即最早被压入队列的元素。
访问队尾元素,如例:q.back(),即最后被压入队列的元素。
判断队列空,如例:q.empty(),当队列空时,返回true。
访问队列中的元素个数,如例:q.size()
【示例代码1】
#include
#include
using namespace std;
int main() {
int e,m;
int len;
queue q;
for(int i=0;i<10;i++){
q.push(i);//入队操作,q.push(x); 将x接到队列的末端
}
if(!q.empty()){//q.empty(),当队列空时,返回true
cout<<"队列非空"<
2、优先队列
priority_queue<int> p;
【常用函数】
(1)priority_queue::empty
判断队列是否为空(也即是size是否为0),是则返回true,否则返回false。优先队列的此成员函数实际上调用底层容器的同名函数。
(2)priority_queue::size
返回队列中元素的个数。此函数实际上调用底层容器的同名函数。这个函数也可以用于判断队列是否为空。
(3)priority_queue::top
返回队头元素的常引用,队头元素是在所设定的比较关系下最大也即优先级最高的元素。此函数实际上调用底层容器的front函数。
(4)priority_queue::pop
清除队头元素。
(5)priority_queue::push给队列插入元素,新元素会按其优先级被排列到适当位置。
q.size();//返回q里元素个数
q.empty();//返回q是否为空,空则返回1,否则返回0
q.push(k);//在q的末尾插入k
q.pop();//删掉q的第一个元素
q.top();//返回q的第一个元素
3、less和greater优先队列
优先队列是优先级高的在队首,定义优先级大小的方式是传入一个算子的参数比较a, b两个东西,返回true则a的优先级。
默认是less算子也就是返回ab,小的优先级高。
如果是默认的less算子,值大的优先级高,自然默认的优先队列大的先出队。
如果是使用greater算子,值小的优先级高,优先队列小的先出队。
priority_queue ,less > p;
priority_queue ,greater > q;
【默认less算子--优先输出大数据】
priority_queue
less算子,即默认算子为:大的往前排,小的往后排(出队时队列头的元素出队,即大者先出队)。
#include
#include
using namespace std;
int main(){
priority_queue p;
p.push(1);
p.push(2);
p.push(8);
p.push(5);
p.push(43);
while(!q.empty()){
cout<
【greater算子--优先输出小数据】
greater算子,即默认算子为:小的往前排,大的往后排(出队时队列头的元素出队,即小者先出队)。
priority_queue, greater > p;
#include
#include
using namespace std;
int main(){
priority_queue, greater >p;
p.push(1);
p.push(2);
p.push(8);
p.push(5);
p.push(43);
while(!q.empty()){
cout<
【自定义算子--重载默认的<符号】
#include
#include
using namespace std;
class T
{
public:
int x, y, z;
T(int a, int b, int c):x(a), y(b), z(c) { }
};
bool operator < (const T &t1, const T &t2)
{
return t1.z < t2.z; // 按照z 的顺序来决定t1 和t2 的顺序
}
int main()
{
priority_queue q;//使用模板T的自定义比较方法
q.push(T(4,4,3));
q.push(T(2,2,5));
q.push(T(1,5,4));
q.push(T(3,3,6));
while (!q.empty())
{
T t = q.top(); q.pop();
cout << t.x << " " << t.y << " " << t.z << endl;
}
return 0;
}
个人更喜欢把自定义算子写成友元的,写进类里:struct情况类似
为了更好地理解自定义算子,下面给出了两个示例代码,
其中一个为上面例子中使用struct,且把自定义算子写进struct内部的情况
另一个为测试Dijkstra模板中HeapNode的测试代码;
【源代码1】
#include
#include
using namespace std;
struct T
{
public:
int x, y, z;
T(int a, int b, int c):x(a), y(b), z(c) { }
friend bool operator < (const T &t1, const T &t2)//自定义less算子,优先输出大数据
{ ////z值小的往前排,z值大的往后排(出队时序列尾的元素出队,即z值大者先出队)
return t1.z < t2.z; // 按照z 的顺序来决定t1 和t2 的顺序,优先输出z值大的大数据
// return t2.z > t1.z;
}
};
int main()
{
priority_queue q;//使用模板T的自定义比较方法
q.push(T(4,4,3));
q.push(T(2,2,5));
q.push(T(1,5,4));
q.push(T(3,3,6));
while (!q.empty())
{
T t = q.top();
q.pop();
cout << t.x << " " << t.y << " " << t.z << endl;
}
return 0;
}
【测试结果1】
3 3 6
2 2 5
1 5 4
4 4 3
【源代码2】
#include
#include
using namespace std;
struct HeapNode //Dijkstra算法用到的优先队列的节点
{
int d,u;
HeapNode(int d,int u):d(d),u(u){}
bool operator < (const HeapNode &rhs)const //自定义less算子,优先输出大数据
{ //按照d的顺序来决定自身HeapNode和rhs的顺序,优先输出d值大的大数据
//return d > rhs.d; 这两种写法是一样的
return rhs.d q;//使用模板T的自定义比较方法
q.push(HeapNode(4,3));
q.push(HeapNode(2,5));
q.push(HeapNode(1,4));
q.push(HeapNode(3,6));
while (!q.empty())
{
HeapNode n = q.top(); q.pop();
cout << n.d << " " << n.u << endl;
}
return 0;
}
【测试结果2】
1 4
2 5
3 6
4 3
以下例子帮助理解大根堆、小根堆:
#include
#include
#include
using namespace std;
int main(int argc, char** argv) {
//priority_queue,greater>q;//greater是小根堆,从小到大输出
priority_queue,less>q; // less是大根堆, 从大到小输出
//priority_queueq默认从大到小排序(大根堆)
int n;
int x;
while(cin>>n){
for(int i=0;i>x;
q.push(x);
}
while(!q.empty()){
int x=q.top();
cout<
相关链接1
相关链接2
相关链接3