STL —— priority_queue的用法及实例
Priority Queue的概念及性质
队列结构可以用来解决很多日常的问题,像是先来先服务的银行柜台等。但是很多场景下,队列这种“先进先出”的简单规则并不能很好的满足问题的需求,例如,在医院就诊时,如果新来的病患病情特别严重,随时都由生命危险,那么此时应该先安排该患者就诊,而不是等待前面先来的患者就诊完再接受治疗,这样可能会耽误治疗的最佳时机。
对于病情严重情况、到医院时间早晚这些信息,都可以将它们进行量化和比较,因此可以将它们的大小视为优先级(Priority),而这种能够将数据按照事先规定的优先级次序进行动态组织的数据结构称为优先队列(Priority Queue)。
优先队列与队列基本相似,从一端插入(队尾),从另一端删除(队首),并且每次只能访问位于队首的元素,即队首的元素先出队。
优先队列中,每个元素都被赋予了优先级,访问元素时,只能访问当前队列中优先级最高的元素。
因此,priority_queue容器适配器中元素的插入和删除操作,遵循的并不是简单的先入先出(First-In-First-Out,FIFO)原则,而是*先出(First-In Greatest-Out)原则,即最先进队列的元素不一定先出队列,优先级最大的元素最先出队列。
STL——priority_queue的用法
在C++的标准库中提供了优先队列模板,优先队列底层是用二叉堆实现的,但读者无需关心其内部的实现细节,只需要掌握如何使用即可。
基本操作包括:
- 判空 empty()
- 元素个数 size()
- 添加 push()、emmplace() (c++11)
- 删除 pop()
- 优先级最高元素 top()
- 交换 swap() (c++11)
- 首先,要使用标准库中的priority_queue模板,应该在头文件中添加头文件:
#include<queue>
- 定义一个优先队列priority_queue
//priority_queue<typename> name;
//typename 是队列元素的类型,name是所定义优先队列的名字,例如
priority_queue<int> myPriorityQueue;
- 判断当前优先队列是否为空
myPriorityQueue.empty(); //若为空返回true
- 返回当前优先队列元素的个数
myPriorityQueue.size();
- 添加新元素
myPriorityQueue.push(x);
myPriorityQueue.emplace(x);
对于这两个操作,push的操作可以直接用于emplace,唯一需要注意的是,emplace可以直接传入构造对象需要的元素,然后自己调用其构造函数;而push只能让其构造函数构造好对象之后,再使用复制构造函数。也就是说push多了复制这一步,所以emplace更节省内存。
- 删除元素
myPriorityQueue.pop();
- 访问元素
由于优先队列对访问元素的限制,优先队列只能通过top()访问当前队列中优先级最高的元素。
myPriorityQueue.top();
- 将两个priority_queue中的元素进行互换,注意元素类型必须相同
//C++11
priority_queue<int> foo;
priority_queue<int> bar;
foo.push(10); foo.push(20); foo.push(30);
bar.push(100); bar.push(200);
foo.swap(bar); //交换元素
//swap(foo, bar); //也可以
经过这样的操作,bar和foo中的元素进行了交换,现在,bar中的元素为30,20,10;foo中的元素为200,100。
实例
下面我给出一个简单的实例对priority_queue的用法做个总结。
#include<iostream>
#include<queue>
using namespace std;
int main(){
//1.定义
priority_queue<int> myPriorityQueue;
//2.获得队列长度,目前还没有任何元素进队,所以应该为0
cout<<"the size of myPriorityQueue: "<<myPriorityQueue.size()<<endl;
//3.入队,数字1-9入队
for(int i=1; i<10; i++){
myPriorityQueue.push(i);
}
//4.访问队列长度、优先级最高元素
cout<<"the size of myPriorityQueue: "<<myPriorityQueue.size()<<endl;;
cout<<"the top of myPriorityQueue: "<<myPriorityQueue.top()<<endl;
//5.访问整个队列并计算总和
int sum = 0;
while(!myPriorityQueue.empty()){
int tmp = myPriorityQueue.top(); //记录优先级最高元素
sum += tmp;
cout<<tmp<<" ";
myPriorityQueue.pop();
}
cout<<endl;
cout<<"sum: "<<sum<<endl;
//6.判断优先队列是否为空,由于上个操作删除了队列中的所有元素,故现在队列为空
if(myPriorityQueue.empty()){
cout<<"myPriorityQueue is empty."<<endl;
}
//7.1交换两个队列元素
priority_queue<int> foo;
priority_queue<int> bar;
foo.push(10); foo.push(20); foo.push(30);
bar.push(100); bar.push(200);
// foo.swap(bar);
swap(foo,bar);
//7.2输出交换后的各个队列的元素
cout<<"foo: ";
while(!foo.empty()){
int tmp1 = foo.top();
cout<<tmp1<<" ";
foo.pop();
}
cout<<endl;
cout<<"bar: ";
while(!bar.empty()){
int tmp2 = bar.top();
cout<<tmp2<<" ";
bar.pop();
}
return 0;
}
执行结果为:
上一篇: ACWing164可达性统计(拓扑排序+bitset)
下一篇: 手写简单RPC实现