[LeetCode刷题笔记] C++ priority_queue常用操作
在[1]对常用的STL容器进行了概览,笔者在刷题过程中经常需要查询一些STL容器的函数,实为不便,因此在此对STL容器中常用的操作进行笔记。
std::priority_queue<T>
定义于头文件<queue>
中,是所谓的优先队列,一般的队列,如同[2]中所示,是先进先出的,不需要对插入对象的大小或者其他属性进行排序等,而优先队列可以提供插入对象与现存对象之间的比较机制,这种机制可以给每个元素提供优先级,从而在队列出列时,可以按照优先级的大小,升序或者降序出列。这种机制在实现操作系统的ready进程出列,给CPU运算时经常使用,因为不同的进程是有优先级的,经常需要按照进程的优先级进行出列。
注意到priority_queue<T>
并不是一种原生的序列数据结构,而是一种容器类序列数据结构,其意思是,实现优先队列的底层数据结构可以是vector<T>
,也可以是deque<T>
,只要是满足可以定义以下函数的数据类型都行:front()
, push_back()
, pop_back()
。
其类原型如:
template<
class T,
class Container = std::vector<T>,
class Compare = std::less<typename Container::value_type>
> class priority_queue;
这里的Container
就是在指定容器类型,默认是用vector<T>
实现的;Compare
指定比较元素的方法,默认是less<T>
降序,这里的less<T>
的意思是最大优先级的元素将会在top()
出现,而相反的,greater<T>
的意思是最小优先级的元素将会在top()
出现。 注意到,优先队列可以对最大或者最小优先级的元素在常数时间内的查找,但是插入和删除时间都是对数级别的。 其常用操作也不多,如下例子所示:
push()
插入元素,并且对底层容器排序pop()
弹出栈顶元素,注意不返回值top()
返回栈顶元素,注意不弹出empty()
判断队列是否为空size()
返回队列尺寸
priority_queue<int, vector<int>, less<int>> lessq;
priority_queue<int, vector<int>, greater<int>> greatq;
vector<int> nums = {2,3,6,8,0,1,5}; // 假设数值大小表示每个元素的优先级
for (auto &n:nums) {
lessq.push(n);
greatq.push(n);
}
while (!lessq.empty()){
cout << lessq.top() << " ";
lessq.pop();
} // 输出 8,6,5,3,2,1,0 大优先级的先出列
while (!greatq.empty()){
cout << greatq.top() << " ";
greatq.pop();
} // 输出 0,1,2,3,5,6,8 小优先级的先出列
也可以自定义比较函数:
struct node {
int x, y;
node(int x, int y):x(x), y(y){}
};
struct cmp {
bool operator()(node a, node b){
if (a.x == b.x) return a.y >= b.y;
else return a.x > b.x;
}
};
int main() {
priority_queue<node, vector<node>, cmp> pq;
for(int i = 1; i <= 5; i++)
for(int j = 1; j <= 5; j++)
pq.push(node(i,j));
while (!pq.empty()) {
cout << pq.top().x <<" " << pq.top().y <<endl;
pq.pop();
}
return 0;
}
输出如:
我们可以发现,priority_queue<T>
是一个最大堆,其默认使用std:less<T>
,也就意味着,其使用了操作符operator<
。这意味着如果这个比较返回false
,那么第一个参数的元素位置将会和top()
更接近[4]。
因此 less<int>
等价于下面的自定义比较结构cmp
struct cmp {
bool operator()(int a, int b) {
return a < b; // 这里是小于号,也即是为什么叫`less`的原因,但是其实最大优先级的先出列。
}
}
Reference
[1]. https://blog.csdn.net/LoseInVain/article/details/104189784
[2]. https://blog.csdn.net/LoseInVain/article/details/104453697
[3]. https://stackoverflow.com/questions/16111337/declaring-a-priority-queue-in-c-with-a-custom-comparator
[4]. https://stackoverflow.com/questions/36069276/what-does-the-return-value-of-a-priority-queue-custom-comparator-signify