【C++/STL】6. priority_queue优先队列
原创
©著作权归作者所有:来自51CTO博客作者云端FFF的原创作品,请联系作者获取转载授权,否则将追究法律责任
- 优先队列底层是靠堆实现的,是一种特殊的队列。
- 优先队列的队首元素一定是当前队列中优先级最高的那个,也就是说,如果把优先队列中元素依次出队,会得到按优先级从大到小排列的一组元素
- 向优先队列中插入元素时,优先队列内部的堆结构会自动调整,保证队首元素永远是优先级最高的。
- priority_queue定义于
queue.h
,命名空间std
一、构造函数
作用
| 代码
| 说明
|
定义一个priority_queue
| priority_queue<typename> pq;
| typename可以是任意基础数据类型或STL容器
|
二、访问priority_queue内元素
- 与queue不同,priority_queue没有
front()
和back()
方法,只能通过top()
方法访问队元素
#include <iostream>
#include <queue>
using namespace std;
int main()
{
priority_queue<int> pq; //默认大数优先级高
pq.push(1);
pq.push(2);
pq.push(3);
pq.push(4);
cout<<pq.top()<<endl; //打印4
pq.pop();
cout<<pq.top()<<endl; //打印3
return 0;
}
三、常用操作
(1)基本操作
操作
| 代码
| 时间复杂度
| 说明
|
元素x入队
| pq.push(x)
| O(logN),N为当前优先队列中元素个数
| -
|
队首出队
| pq.pop()
| O(logN),N为当前优先队列中元素个数
| 出队的是优先级最高的元素
|
队列判空
| pq.empty()
| O(1)
| 返回一个bool类型
|
访问队首元素(不影响队列)
| pq.top()
| O(1)
| 如果队列为空,top()方法会报错
|
获得priority_queue内元素个数
| pq.size()
| O(1)
| -
|
(2)设置优先级
1. 基本数据类型的优先级
- 仅适用于基本数据类型
- 对于int、double等类型,数字越大优先级越高
- 对于char,字典序越大优先级越高
- 对于基本数据类型,
priority_queue<int> q;
等价于priority_queue<int, vector<int>, less<int>> q
- 其中第二个参数
vector
是用来承载底层的堆结构的,这里出现的3个typename应该相同 - 第三个参数
less
是对第一个参数的比较类,less<typename>
代表数字大的优先级高;greater<typename>
代表数字小的优先级高
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
int main()
{
//priority_queue<int> pq; //默认大数优先级高
priority_queue<int,vector<int>,greater<int> > pq; //小数优先级高
pq.push(1);
pq.push(2);
pq.push(3);
pq.push(4);
cout<<pq.top()<<endl; //打印1
pq.pop();
cout<<pq.top()<<endl; //打印2
return 0;
}
2. 结构体优先级设置
- 适用于基本数据类型、结构体和STL容器
- 下面定义一个fruit结构体,希望价格高的结构体优先级高
//方法一----------------------------------------------------
struct fruit
{
string name;
int price;
//重载<运算符
friend bool opreator < (fruit f1,fruit f2)
{
return f1.price < f2.price; //价格高的优先级高
}
};
priority_queue<fruit> q; //定义fruit类型的优先队列,内部就是价格高的fruit优先级高
//方法二----------------------------------------------------
struct fruit
{
string name;
int price;
};
struct cmp
{
//重载<运算符
bool opreator () (fruit f1,fruit f2) //注意这里不写friend,小于号换括号
{
return f1.price < f2.price; //价格高的优先级高
}
};
priority_queue<fruit,vector<fruit>,cmp> q;
- 如果结构体内数据较大,可以在重载运算符时使用常引用来提高效率
friend bool opreator < (const fruit &f1,const fruit &f2)
{
return f1.price < f2.price;
}
bool opreator () (const fruit &f1,const fruit &f2)
{
return f1.price < f2.price;
}