寻找大富翁
寻找大富翁
一、目的
-掌握堆排序
-掌握sort的用法
二、实验内容与设计思想
寻找大富翁
胡润研究院的调查显示,截至2017年底,中国个人资产超过1亿元的高净值人群达15万人。假设给出N个人的个人资产值,请快速找出资产排前M位的大富翁。
输入格式:
输入首先给出两个正整数N(≤10^6)和M(≤10),其中N为总人数,M为需要找出的大富翁数;接下来一行给出N个人的个人资产值,以百万元为单位,为不超过长整型范围的整数。数字间以空格分隔。
输出格式:
在一行内按非递增顺序输出资产排前M位的大富翁的个人资产值。数字间以空格分隔,但结尾不得有多余空格。
输入样例:
8 3
8 12 7 3 20 9 5 18
输出样例:
20 18 12
题目分析:
代码重点在于判断排序条件的函数
1.排序直接使用sort
函数相关伪代码
1.bool compare(int a,int b)
return a>b;
2.
for(i=0;i<x;i++)
|cin>>a[i];
sort(a.begin(),a.end(),compare);
if(x<m)
|m=x;
for(i=0;i<m;i++)
|cout<<a[i];
|if(i<m-1)
||cout<<" ";
函数代码
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
bool compare(int a,int b){
return a>b;
}
int main()
{
int x,m,i;
cin>>x>>m;
vector<int>a(x);
for(i=0;i<x;i++){
cin>>a[i];
}
sort(a.begin(),a.end(),compare);
if(x<m){
m=x;
}
for(i=0;i<m;i++){
cout<<a[i];
if(i<m-1){
cout<<" ";
}
}
return 0;
}
2.使用堆排序
函数相关伪代码
1.交换函数
void swap(int &a,int &d)
int k;
k=a;
a=d;
d=k;
2.调整为最大堆
void tui(vector<int>&a,int n,int m)
k=m;
l=2*m+1;
r=2*m+2;
if(l<n&&a[l]>a[k])
|k=l;
if(r<n&&a[r]>a[k])
|k=r;
if(k!=m)
|swap(a[m],a[k]);
|tui(a,n,k);
3.排序
void tui1(vector<int>&a,int n,int m)
for(i=n/2-1;i>=0;i--)
|tui(a,n,i);
for(i=n-1;i>=n-m;i--)
|swap(a[0],a[i]);
|tui(a,i,0);
4.主函数
for(i=0;i<n;i++){
|cin>>a[i];
if(n<m)
|m=n;
tui1(a,n,m);
for(i=n-1;i>=n-m;i--)
|cout<<a[i];
|if(i>n-m){
||cout<<" ";
函数代码
#include<iostream>
#include<vector>
using namespace std;
void swap(int &a,int &d){
int k;
k=a;
a=d;
d=k;
}
void tui(vector<int>&a,int n,int m)
{
int k=m;
int l=2*m+1;
int r=2*m+2;
if(l<n&&a[l]>a[k]){
k=l;
}
if(r<n&&a[r]>a[k]){
k=r;
}
if(k!=m){
swap(a[m],a[k]);
tui(a,n,k);
}
}
void tui1(vector<int>&a,int n,int m){
int i;
for(i=n/2-1;i>=0;i--){
tui(a,n,i);
}
for(i=n-1;i>=n-m;i--){
swap(a[0],a[i]);
tui(a,i,0);
}
}
int main()
{
int n,m,i;
cin>>n>>m;
vector<int>a(n);
for(i=0;i<n;i++){
cin>>a[i];
}
if(n<m){
m=n;
}
tui1(a,n,m);
for(i=n-1;i>=n-m;i--){
cout<<a[i];
if(i>n-m){
cout<<" ";
}
}
return 0;
}
时间复杂度为nlog(n),空间复杂度为O(n)
三、实验使用环境
以下请根据实际情况编写
- 操作系统:Windows 11专业版
- 编程语言:C++
- 开发工具:[Visual Stdio 2022]
四、实验步骤和调试过程
寻找大富翁
本机运行截图
运行分析
输入的第一个值是有多少人符合要求,第二个是输出人数
输出:
对于sort函数,数组已经全部排序好了,从最大到最小,输出时只要数组前m个就好
对于堆函数,要几个就排几个,并没有全部排好,求是按照最小到最到大,输出从数组最后开始输出m个
五、实验小结
遇到的问题及解决方法:
- 问题:判断函数逻辑有问题
- 解决方法:修改代码
实验体会和收获:
这段C++代码用于对输入的整数数组进行排序并输出前m个最大的数。
对于sort函数(STL库自带),给它起点和终点,数组会自动排序,最后只要输出,操作简单。
对于堆排列,代码首先定义了交换函数swap和调整堆结构的函数tui,然后通过tui1函数构建最大堆并进行堆排序。
把数组看成树,奇数是左孩子,偶数是右孩子,调用tui函数来调整堆的结构,用a[m]来和其左右孩子比较,如果左(右)孩子(左孩子下标为2m+1,右孩子下标为2m+2)大于a[m],记住其下标,最后交换两个值,再递归,直到值大于左右孩子,这时堆就调整好了。
tui1函数先从前面i=n/2-1(是为了从最后一个非叶节点开始调整)进行对堆的调整排序,之后从n-1开始不断与a[0]交换,再调整堆,直到结束,对于后面m个数就排好了序。
在main函数中,读取输入数据,用vector