堆排序的解决算法(基本)

#1105:题外话:堆

#1105 : 题外话·堆

时间限制: 10000ms
单点时限: 1000ms
内存限制: 256MB

描述

小Ho有一个糖果盒子,每过一段时间小Ho都会将新买来的糖果放进去,同时他也会不断的从其中挑选出最大的糖果出来吃掉,但是寻找最大的糖果不是一件非常简单的事情,所以小Ho希望能够用计算机来他帮忙计算这个问题!

提示:吃糖果吃多了会变胖的!

输入

每个测试点(输入文件)有且仅有一组测试数据。

在一组测试数据中:

第1行为1个整数N,表示需要处理的事件数目。

接下来的M行,每行描述一个事件,且事件类型由该行的第一个字符表示,如果为'A',表示小Ho将一粒糖果放进了盒子,且接下来为一个整数W,表示这颗糖果的重量;如果为'T',表示小Ho需要知道当前盒子中最重的糖果的重量是多少,在知道这个值之后,小Ho会将这颗糖果从盒子中取出并吃掉。

对于100%的数据,满足1<=N<=10^5, 1<=w<=10^5。<>

对于100%的数据,满足没有2颗糖果的重量是相同的,最开始的时候小Ho的糖果盒子是空的,且每次小Ho想要取出一颗糖果的时候盒子里一定至少有一颗糖果。

输出

在一组测试数据中:

对于每个类型为'T'的时间,输出1个整数W_MAX,表示在这一时刻,盒子中最重的糖果的重量。


样例输入
5
A 77751
A 1329
A 26239
A 80317
T
样例输出
80317
对于这个题是个明显的堆排序的题。对于这个题是先建完全二叉树:先用一个全局变量来记录这个数组的最后一个数的位置的下一个位置(bj),设置一个数组存储这个树(p【100000】)(注意:这个堆的同一层是无序的,不需要排序)
1、输入一个数x,若这个数是第一个数,就是根,就直接赋值给数组的第一个,bj++,return结束;否则就转2
2、这个数不是第一个数,就直接p【bj】=x,然后整理这个树,让它成为大顶堆。进行循环若bj/2不等于0(意思是不为根结点)和p【bj】>p[bj/2](意思是底下的子数大于他的根),进行对调他的子树与根的值(就是p【bj】与p【bj/2】交换数值),然后使bj=bj/2;转换到上一层,防止因为换完之后不符合每个小树不是一个大顶堆。不断重复这个循环,直到循环停止。在之前需要设置一个变量来记录最后一个数的位置,记住要加1.
对于输出最大值,然后在整理缺少根结点的树。对于这个完全二叉树,我们知道他的根结点是最大的这个树的最大值,然后直接用一个变量来返回这个最大值ans。对于返回之后的整理,因为少了一个值,需要将标记bj减1,最后的一个值付给p【1】;然后将这个树在进行整理,设置a=1,循环就是当a的两个子树a*2小于bj(防止乘以一个数值之后发生超出这个树的结点个数)且根结点a小于他的子树(a*2)或者
当a的两个子树a*2+1小于bj(防止乘以一个数值之后发生超出这个树的结点个数)且根结点a小于他的子树(a*2+1),然后就分三种情况:他的两个子树都大于根{if(他的左子树大于右子树){就交换左子树与父节点的值,并使a=a*2}else{就交换右子树与父节点的值,a=a*2+1}};只有他的左子树大于父节点,、{
就交换左子树与父节点的值,并使a=a*2;
};只有右子树大于父节点{
就交换左子树与父节点的值,并使a=a*2+1;
}
返回ans就行
#include<stdio.h>
int data[120010];
int bj;
void ADD(int x){
	int a,b;
	if(bj==1){
		data[bj]=x;
		bj++;
		return;
	}
	else{
		data[bj]=x;
		a=bj+1;
		while(bj/2&&data[bj]>data[bj/2]){
			b=data[bj];
			data[bj]=data[bj/2];
			data[bj/2]=b;
			bj=bj/2;
		}
		bj=a;
		return ;
	}
}
int delet(){
	bj--;
	int ans=data[1];
	data[1]=data[bj];
	int a=1,b;
	while((bj>a*2&&data[a]<data[a*2])||(bj>a*2+1&&data[a]<data[a*2+1])){
		if((bj>a*2&&data[a]<data[a*2])&&(bj>a*2+1&&data[a]<data[a*2+1])){
			if(data[a*2]>data[a*2+1]){
				b=data[a];
				data[a]=data[a*2];
				data[a*2]=b;
				a=a*2;
			}
			else{
				b=data[a];
				data[a]=data[a*2+1];
				data[a*2+1]=b;
				a=a*2+1;
			}
		}
		else
		if(bj>a*2&&data[a]<data[a*2]){
			b=data[a*2];
			data[a*2]=data[a];
			data[a]=b;
			a=a*2;
		}
		else{
			b=data[a*2+1];
			data[a*2+1]=data[a];
			data[a]=b;
			a=a*2+1;
		}
	}
	return ans;
}
int main(){
	int n,x;
	char zm; 
	scanf("%d",&n);
	getchar();
	bj=1;
	while(n--){
		scanf("%c",&zm);
		getchar();
		if(zm == 'A'){
			scanf("%d",&x);
			getchar();
			ADD(x);
		}
		else{
			int tt=delet();
			printf("%d\n",tt);
		}
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/shi201619616/article/details/78640286