C++ STL priority_queue 优先队列
1.基本概念
优先队列: 与队列的用法是一样的,优先队列内部是通过堆排序实现的。
因为push和pop方法会导致元素变化,故而需要重新调整堆,而top是把堆顶元素输出。
priority_queue< type, container, function >
- type:数据类型;
- container:实现优先队列的底层容器;
- function:元素之间的比较方式;默认写法是大顶堆,对应输出是逆序数组。
2.存储int型写法
#include <iostream> #include <queue> using namespace std; int main(){ //默认是大顶堆 priority_queue<int> large; // 这两种写法是相同的 priority_queue<int,vector<int>, less<int>> large; // 第一个int表示队列的元素类型,这里一定要有空格,不然成了右移运算符 priority_queue<int, vector<int>, greater<int> > small; //小顶堆,升序 for (int i = 0; i < 5; i++){ large.push(i); small.push(i); } while (!large.empty()){ cout << large.top() << ' '; large.pop(); } //输出结果:4 3 2 1 0 cout << endl; while (!small.empty()){ cout << small.top() << ' '; small.pop(); } //输出结果:0 1 2 3 4 return 0; }
3.存储pair<int,int>型写法
先按照pair的first元素排序,first元素相等时,再按照second元素排序
#include<iostream> #include<vector> #include<queue> using namespace std; int main(){ priority_queue<pair<int,int> > pq;//大顶堆 //priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int>> > small;//小顶堆 pair<int,int> a(3,4); pair<int,int> b(3,5); pair<int,int> c(4,3); pq.push(c); pq.push(b); pq.push(a); while(!pq.empty()) { cout<<pq.top().first<<"\t"<<pq.top().second<<endl; pq.pop(); } return 0; }
通过构建仿函数,实现自定义的排序方式;先按照pair的second元素排序,second元素相等时,再按照first元素排序
#include<iostream> #include<vector> #include<queue> using namespace std; struct cmp{ bool operator()(pair<int,int> a,pair<int,int> b){ if(a.second==b.second) return a.first>a.first; else return a.second>b.second; } }; int main(){ priority_queue<pair<int,int>,vector<pair<int,int>>,cmp> pq;//大顶堆 //priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int>> > small;//小顶堆 pair<int,int> a(3,4); pair<int,int> b(3,5); pair<int,int> c(4,3); pq.push(c); pq.push(b); pq.push(a); while(!pq.empty()) { cout<<pq.top().first<<"\t"<<pq.top().second<<endl; pq.pop(); } return 0; }
4.自定义类型的写法
有两种方式,一种是重载<或>,还有一种是重写仿函数,对应的代码如下
#include "queue" #include"vector" #include"iostream" #include"algorithm" using namespace std; class Node { public: int x; int y; Node(int _x, int _y): x(_x), y(_y){} }; bool operator<(Node a,Node b){//重写运算符<,对应的是less return a.x<b.x; } struct cmp{//重写仿函数 bool operator()(Node a,Node b){ return a.y>b.y; } }; int main(){ priority_queue<Node,vector<Node>,less<Node>> pq;//大顶堆 //priority_queue<Node,vector<Node>,cmp> pq;//这种写法效果同上 Node a(3,4); Node b(3,5); Node c(4,3); pq.push(c); pq.push(b); pq.push(a); while(!pq.empty()) { cout<<pq.top().x<<"\t"<<pq.top().y<<endl; pq.pop(); } return 0; }
leetcode 优先队列示例:
https://github.com/AntonioSu/leetcode/blob/master/problems/239.SlidingWindowMaximum.md
https://github.com/AntonioSu/leetcode/blob/master/problems/295.FindMedianfromDataStream.md