数据结构实验之排序四:寻找大富翁
Time Limit: 200MS
Memory Limit: 512KB
Problem Description
2015胡润全球财富榜调查显示,个人资产在1000万以上的高净值人群达到200万人,假设给出N个人的个人资产值,请你快速找出排前M位的大富翁。
Input
首先输入两个正整数N( N ≤ 10^6)和M(M ≤ 10),其中N为总人数,M为需要找出的大富翁数目,接下来给出N个人的个人资产,以万元为单位,个人资产数字为正整数,数字间以空格分隔。
Output
一行数据,按降序输出资产排前M位的大富翁的个人资产值,数字间以空格分隔,行末不得有多余空格。
Example Input
6 3 12 6 56 23 188 60
Example Output
188 60 56
Hint
请用堆排序完成。
Author
xam
建议看一下堆排序定义:点击打开链接
#include <iostream>
#include <stdlib.h>
using namespace std;
//用数组模拟二叉堆,数组中的节点坐标为i,则它的父节点的坐标为(i - 1) / 2
//通过比较数据和它父节点的大小,调整为最小堆或者最大堆
void MinHeapFixup(int a[], int i, int m)
{
int j, temp;
temp = a[i]; //记录下这个节点值
j = 2 * i + 1; //找到它父节点的节点位置
while(j < m) //当这个节点不是头节点的时候,父节点才有意义
{
if (j + 1 < m && a[j] > a[j + 1]) //在左右孩子中找最小的
j++;
if(a[j] >= temp) //如果这个节点比父节点小,没必要调整
break;
a[i] = a[j]; //把较大节点向下移,然后替换
i = j;
j = 2 * i + 1;
}
a[i] = temp;
}
void msort(int a[], int m) //对所有的数据再进行最后的堆排序
{
for(int i = m - 1; i > 0; i--)
{
int t = a[0];
a[0] = a[i];
a[i] = t;
MinHeapFixup(a, 0, i);
}
}
int main()
{
ios::sync_with_stdio(false);
int x, n, m, a[11];
cin >> n >> m;
for(int i = 0; i < m; i++) //限定的内存太小,只能通过不断地开辟新的,用小堆不断拓展
cin >> a[i];
for(int i = m / 2 - 1; i >= 0; i--) //调整堆的顺序
MinHeapFixup(a, i, m);
for(int i = m; i < n; i++) //添加元素,更新最小堆
{
cin >> x;
if(x <= a[0])
continue;
a[0] = x;
for(int j = m / 2 - 1; j >= 0; j--) //每次添加新的元素,重新排序
MinHeapFixup(a, j, m);
}
msort(a, m);
for(int i = 0; i < m - 1; i++)
cout << a[i] << " ";
cout << a[m - 1] << endl;
return 0;
}