数据结构实验之排序四:寻找大富翁
Time Limit: 200 ms Memory Limit: 512 KiB
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
xam
#include<stdio.h>
#define maxn 12
int a[maxn];
int n,m;
void Heapjust(int low, int high)
{
if(low < high)
{
int i, temp = a[low];先取出当前元素i
for(i = 2 * low; i <= high; i *= 2)//从i结点的左子结点开始,也就是2i+1处开始,我这里是从1开始计入的数
{
if(i < high && a[i] > a[i + 1])//如果左儿子小于右儿子,则指向右儿子
{
i++;
}
if(temp < a[i])break;//如果子节点小于父亲节点,将子节点赋值给父节点,不用交换,否则跳出来
a[low] = a[i];
low = i;
}
a[low] = temp;//将temp值放到最终的位置
}
}
int main()
{
int i, j, t, temp;
while(~scanf("%d%d",&n,&m))
{
for(i = 1; i <= m; i++)
{
scanf("%d",&a[i]);
}
//建立大顶堆
for(i = m / 2; i > 0; i--) //从第一个非叶子结点从下至上,从右至左调整结构
{
Heapjust(i,m);
}
for(i = m + 1; i <= n; i++)
{
scanf("%d",&t);
if(a[1] >= t)
{
continue;
}
a[1] =t;
for(j = m / 2; j > 0; j--)
{
Heapjust(j,m);
}
}
for(i = m;i > 0;i --)
{
temp = a[1]; //交换头结点与末尾元素
a[1] = a[i];
a[i] = temp;
Heapjust(1,i-1);//重新对堆进行调整
}
for(i = 1; i <= m; i++)
{
printf("%d%c",a[i],i == m?'\n':' ');
}
}
return 0;
}