洛谷 P3378 【模板】堆

洛谷 P3378 【模板】堆

洛谷 P3378 【模板】堆

菜鸟生成记(90)

复习一下数据结构的堆排序,顺带复习一下堆,在洛谷找个板子题练一下,还行;

这一题还可以用优先队列priorityqueue,STL yyds

[手写堆]

#include<iostream>
#include<stdio.h>
using namespace std;
const int N=1e6+10;
int a[N];
void heap1(int *a,int rt,int n) {//删除堆顶元素后,维护堆 
/*
维护小顶堆(堆顶为最小值) 
堆顶元素与堆底元素交换后,数组长度减1,堆顶元素出堆,
然后维护堆(重构堆),自顶向下维护堆 
*/ 
	int max1=rt;
	int l=2*rt;
	int r=2*rt+1;
	if(r<=n&&a[r]<a[max1]) {
		max1=r;
	}
	if(l<=n&&a[l]<a[max1]) {
		max1=l;
	}
	if(max1!=rt) {
		swap(a[max1],a[rt]);
		heap1(a,max1,n);//前往儿子(左或右) 
	}
}
void heap2(int *a,int rt) {//在堆底插入元素后,维护堆
/*
维护小顶堆(堆顶为最小值) 
堆底(数组尾部)插入一个元素,
自下而上维护堆 
*/
	if(a[rt]<a[rt/2]&&rt/2>=1){//判断是否小于父亲的值 
		swap(a[rt],a[rt/2]);//交换 
		heap2(a,rt/2);//前往父亲
	}
}
/*
8
1 3
1 5
1 6
1 2
1 7
2
3
2
*/
int main() {
	int t;
	int len=0;
	scanf("%d",&t);
	for(int i=0; i<t; i++) {
		int op;
		scanf("%d",&op);
		if(op==1) { //入堆(堆底插入元素)
			int x;
			scanf("%d",&x);
			a[++len]=x;
			heap2(a,len);//自下而上维护堆 
		} else if(op==2) { //输出最小元素
			printf("%d\n",a[1]);
		} else { //堆顶出堆(删除最小元素)
			swap(a[1],a[len]);//堆顶与堆底最后一个元素交换 
			len--;//堆底最后一个元素逻辑删除 
			heap1(a,1,len);//自上而下维护堆 
		}
	}
	return 0;
}

[优先队列priority_queue]

#include<iostream>
#include<stdio.h>
#include<vector>
#include<queue> 
using namespace std;
//创建小顶堆 ,以vector为辅助数组,参数:greater<int>(创建小顶堆);less<int>(创建大顶堆) 
priority_queue<int,vector<int>,greater<int> >q; 
int main() {
	int t;
	int len=0;
	scanf("%d",&t);
	for(int i=0; i<t; i++) {
		int op;
		scanf("%d",&op);
		if(op==1) { //入堆(堆底插入元素)
			int x;
			scanf("%d",&x);
			q.push(x);
		} else if(op==2) { //输出最小元素
			printf("%d\n",q.top());
		} else { //堆顶出堆(删除最小元素)
			q.pop();
		}
	}
	return 0;
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值