数据结构-模板-大根堆小根堆(优先队列)

大部分情况直接套优先队列就可以了的说,先附上优先队列

priority_queue<int,vector<int>,less<int> > maxheap;//大根堆,不写第二个第三个参数默认以vector<int>作容器的大根堆
priority_queue<int,vector<int>,greater<int> > minheap; //小根堆

top //访问队头元素
empty //队列是否为空
size //返回队列内元素个数
push //插入元素到队尾 (并排序)
emplace //原地构造一个元素并插入队列
pop //弹出队头元素
swap //交换内容

//提供一种重载 () 来自定义排序的方式,假设我们自定义了一种node结构体,我们要把它压入优先队列
struct node{
  int date1,date2;
};
struct cmp1{
  bool operater()(const node &x,const node &y){
        return x.date1>y.date1//date1小的优先,和sort相反
  {
};
struct cmp2{
  bool operater()(const node &x,const node &y){
         if(x.date1!=y.date1) return x.date1>y.date2;//date1小的优先,和sort相反
         return x.date2<y.date2;//如果date1相等,date2大的优先
  {
};

但是有些题目你不手写二叉堆不行,下面是手巧的(虽然还没手写过,,),插入,删除的时间复杂度为O(logn)

#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
typedef long long ll;
typedef unsigned long long ull;
const ll MAXN=1e18;
const int MOD=1e6;

struct Maxheap{
    int cnt,date[100050];
    void low(int k){//下沉
        int nex=k*2,tmp=date[k];
        while(nex<=cnt){
            if(nex+1<=cnt&&date[nex+1]>date[nex]) ++nex;
            if(tmp<date[nex]) date[k]=date[nex];
            else break;
            k=nex;nex*=2;
        }
        date[k]=tmp;
    }
    void up(int k){//上浮
        int tmp=date[k];
        while(k>1&&date[k/2]<tmp){
            date[k]=date[k/2];
            k/=2;
        }
        date[k]=tmp;
    }
    void insert(int elem){//插入
        date[++cnt]=elem;
        up(cnt);
    }
    void pop(){//首部删除
        date[0]=date[cnt];
        --cnt;
        low(0);
    }
    void init(){//对date内部元素进行初始化
        if(cnt==1) return;
        int pos;
        for(pos=cnt;pos>=1;--pos){
            if(pos*2<=cnt) break;
        }
        while(pos>=1){
            low(pos);
            --pos;
        }
    }
    void print(){//输出
        for(int i=1;i<=cnt;++i){
            cout<<date[i]<<' ';
        }
        cout<<'\n';
    }
}maxh;

struct Minheap{
    int cnt,date[100050];
    void low(int k){
        int nex=k*2,tmp=date[k];
        while(nex<=cnt){
            if(nex+1<=cnt&&date[nex+1]<date[nex]) ++nex;
            if(tmp>date[nex]) date[k]=date[nex];
            else break;
            k=nex;nex*=2;
        }
        date[k]=tmp;
    }
    void up(int k){
        int tmp=date[k];
        while(k>1&&date[k/2]>tmp){
            date[k]=date[k/2];
            k/=2;
        }
        date[k]=tmp;
    }
    void insert(int elem){
        date[++cnt]=elem;
        up(cnt);
    }
    void pop(){
        date[0]=date[cnt];
        --cnt;
        low(0);
    }
    void init(){
        if(cnt==1) return;
        int pos;
        for(pos=cnt;pos>=1;--pos){
            if(pos*2<=cnt) break;
        }
        while(pos>=1){
            low(pos);
            --pos;
        }
    }
    void print(){
        for(int i=1;i<=cnt;++i){
            cout<<date[i]<<' ';
        }
        cout<<'\n';
    }
}minh;
posted @ 2021-04-11 14:15  七铭的魔法师  阅读(344)  评论(0编辑  收藏  举报