用堆实现求第K大的数

题目来源SZUOJ  L35


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int size;
int k;
int arr[100009];
//维持K个元素的大堆
void _swap(int &a,int &b)
{
	int tmp=a;
	a = b;
	b =tmp;
}
//先用插入的数放到堆顶,然后下沉
void sink(int num)
{
	int parent,child;
	parent = 1;
	child = parent<<1;
	arr[1]=num;

	//
	while(child<=k)
	{
		if(child+1<=k && arr[child+1]>arr[child])
			child++;
		if(arr[child]<=arr[parent])
			break;
		_swap(arr[child],arr[parent]);
		parent = child;
		child = child<<1;
	}
	//printf("%d\n",arr[1]);
}
//构建大堆
void swim(int num)
{
	int child = size;
	int parent = child>>1;
	arr[size++] = num;

	while(parent)
	{
		if(arr[parent]<arr[child])
			_swap(arr[parent],arr[child]);
		child = parent;
		parent>>=1;
	}
}
int main()
{
	int t;
	int opernum;
	char coper[6];
	int cur = 0;
	int num;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d %d",&opernum,&k);
		size = 1;
		while(opernum--)
		{
			scanf("%s",coper);
			if(coper[1]=='d')//if "add"
			{
				scanf("%d",&num);
				if(size<=k)
				{
					swim(num);
					//arr[size++] = num;
				}
				else
				{
					if(num<arr[1])
					{	
						sink(num);
						size++;
					}
				}
			}
			else  //ask;
			{
				if(size<=k)
					printf("error\n");
				else
				{
					printf("%d\n",arr[1]);
				}	
			}
		}
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值