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

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

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

推荐浏览: 白话经典算法系列之七 堆与堆排序 +啊哈算法
blablabla: 节约时间之竟然还有这种操作系列。。。
因保留多的大富翁资产,所以只存多的几个就行。存完再堆排序。



排出最大堆之后,交换h[1]和h[n],堆的大小减一,并将h[1]向下调整以保持堆的特性。
最后得到按照从小到大排序的序列。(同理也可排出最小堆后,交换得到从大到小的序列)
1.堆排序 (from Aha Algorithms)
#include <bits/stdc++.h>
using namespace std;
int h[1011200];
void swap(int x, int y)//交换
{
    int t;
    t = h[x];
    h[x] = h[y];
    h[y] = t;
    return ;
}
void siftdown(int i, int n)//向下调整
{
    int t, flag = 0;
    while(i*2 <= n && flag == 0)//先判断是否有左儿子,是否需要继续执行。
    {
        if(h[i] < h[i*2])//找到父子中最大的,若不是父亲本身则交换。
        {
            t = i*2;
        }
else t= i; if(i*2+1 <= n && h[t] < h[i*2+1]) { t = i*2+1; } if(t != i) { swap(t, i); i = t; } else flag = 1;//否则说明当前父结点已比两个儿子大了,不需要继续调整了 } return ;}void creat(int n){ int i; for(i = n/2; i >=1; i--)//叶节点无需调整,所以从最后一个非叶节点(编号为 n/2)至根节点开始向下调整, { siftdown(i,n); } return ;}void heapsort(int n)//堆排序{ while(n > 1) { swap(1,n); n--; siftdown(1,n); } return ;}int main(){ int m; int i,j; int n; int k=1; while(cin>>n>>m)//为了减小数据量,只保留前m个大的财富值。 { for(i=1; i<=n; i++) { int t; scanf("%d",&t); if(k < m+1) h[k++] = t; else { int l=1; for(j=2; j<k; j++) { if(h[l] > h[j]) l = j; } if(h[l] < t) h[l] = t; } } int num = n; creat(m); heapsort(m); for(i=m; i>1; i--) { printf("%d ",h[i]); } printf("%d",h[i]); } return 0;}



2.快排

sort解决。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值