数据结构实验之排序四:寻找大富翁

数据结构实验之排序四:寻找大富翁

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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值