二叉堆,...

#include<iostream>
#include<stdio.h>
//heap
using namespace std;
const int heap_size=1e7+5;
int len,a[heap_size];
int top(){
	return a[1];//堆顶就是最值
}
void pop(){
	a[1]=a[len--];将末尾节点覆盖堆顶,作用是删除
	int pos=1,lef,rig;
	while(1){
		lef=pos*2,rig=pos*2+1;//左右儿子节点编号
		if(rig<=len){//如果有右节点
			if(a[lef]>a[pos]||a[rig]>a[pos])//根比儿子小,不满足堆的性质
				if(a[lef]>a[rig])swap(a[pos],a[lef]),pos=lef;
				else swap(a[pos],a[rig]),pos=rig;//找大的替换
			else break;//合法退出
		}
		else {
			if(lef<=len)//如果只有左儿子
				if(a[lef]>a[pos])
					swap(a[pos],a[lef]),pos=lef;
				else break;//同理
		}
		if(lef>len)break;//到末尾退出
	}
	
	
}
void push(int x){
	a[++len]=x;//末尾插入
	int pos=len,fa;
	while(a[pos/2]<a[pos]&&pos!=1){//不断往上找,看根节点是否小于儿子节点,不断交换直到堆顶
		fa=pos/2;//父亲点
		swap(a[fa],a[pos]);//换
		pos=fa;更新新节点位置
	}
}
int n;
int main(){
	scanf("%d",&n);
	while(n--){
		int op,x;
		scanf("%d",&op);
		if(op==1)scanf("%d",&x),push(-x);
		if(op==2)printf("%d\n",-top());
		if(op==3)pop();
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值