数据结构实验之排序四:寻找大富翁
Time Limit: 200 ms Memory Limit: 512 KiB
Submit Statistic Discuss
Problem Description
2015胡润全球财富榜调查显示,个人资产在1000万以上的高净值人群达到200万人,假设给出N个人的个人资产值,请你快速找出排前M位的大富翁。
Input
首先输入两个正整数N( N ≤ 10^6)和M(M ≤ 10),其中N为总人数,M为需要找出的大富翁数目,接下来给出N个人的个人资产,以万元为单位,个人资产数字为正整数,数字间以空格分隔。
Output
一行数据,按降序输出资产排前M位的大富翁的个人资产值,数字间以空格分隔,行末不得有多余空格。
Sample Input
6 3
12 6 56 23 188 60
Sample Output
188 60 56
Hint
请用堆排序完成。
Source
从大到小排序:建小顶堆,筛选,最后数组从大到小排列
由大到小 在堆排时 将小顶堆中最小的放到最后在调整其他的,所以最后形成降序
思路:建立一个m大小的小顶堆,
再将剩余n-m个输入与堆顶比较,比堆顶大则把它换成堆顶,维护,
堆排
( 堆排是通过将最后一个元素与堆顶元素交换,再维护剩余i-1个 )
之所以建小顶堆:堆的大小是要求排序的大小即3,堆顶是堆中的最小值,在建堆的过程确保堆顶比剩余的大(不在堆里的),这样来达到堆里是最大的前三个。
#include <stdio.h>
int a[1000001];
void h_adjust(int s,int m)//小顶堆
{ //s~m 调整范围
int i,x;
x=a[s];
for(i=s*2;i<=m;i*=2)
{
if(i+1<=m&&a[i+1]<a[i]) i++;
if(a[i]>=x) break;
a[s]=a[i];s=i;
}
a[s]=x;
}
void h_sort(int n) //堆排
{
int i,t;
for(i=n;i>1;i--)
{
t=a[i];a[i]=a[1];a[1]=t;
h_adjust(1,i-1);
}
}
int main()
{
int n,i,x,r;
scanf("%d%d",&n,&r);
for(i=1;i<=r;i++)
{
scanf("%d",&a[i]);
}
h_adjust(1,r);//建一个r大小的堆
for(i=r+1;i<=n;i++)
{
scanf("%d",&x);
if(x>a[1])
{
a[1]=x; //一边建一边调整
h_adjust(1,r);
}
}
h_sort(r);
for(i=1;i<r;i++) printf("%d ",a[i]);printf("%d\n",a[r]);
return 0;
}