小根堆的两种写法
手写堆
可以视作是一种完全二叉树结构
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;
const int Maxn=1000005;
int sta[Maxn];
int n,tot=0;//tot记录元素总数,记得及时更新
inline int read() {
int x=0,w=1;
char ch=0;
while(ch!='-' && (ch<'0' || ch>'9')) ch=getchar();
if(ch=='-') w=-1,ch=getchar();
while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
return x*w;
}
inline void push(int b) {
sta[++tot]=b;
for(int i=tot,j=i>>1; j; i=j,j=i>>1) {
if(sta[j]>sta[i]) swap(sta[j],sta[i]);
//只需要判断当前节点与父亲的大小关系
}
}
inline void pop() {
sta[1]=sta[tot--];//最小值覆盖掉
for(int i=1,j=i<<1; j<=tot; i=j,j=i<<1) {
if(j+1<=tot&&sta[j+1]<sta[j]) j++;//因为是小根堆,所以在两个兄弟节点之间选取更小的那个向上推
if(sta[i]<sta[j]) break;//此时没有交换的必要
else swap(sta[i],sta[j]);
}
}
int main() {
n=read();
int a,b;
for(int i=1; i<=n; i++) {
a=read();
if(a==1) {
b=read();
push(b);
} else if(a==2) printf("%d
",sta[1]);
else if(a==3) pop();
}
return 0;
}
STL
可以用优先队列
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
using namespace std;
priority_queue <int> q;//定义堆
int n;
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
int opt,x;
scanf("%d",&opt);
if(opt==1) scanf("%d",&x),q.push(-x);//加负号
if(opt==2) printf("%d
",-q.top());//加负号
if(opt==3) q.pop();
}
return 0;
}