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

posted @ 2019-11-22 11:27  suwenyuan  阅读(489)  评论(0编辑  收藏  举报