计数排序讲解和【题解】——选举学生会

1.计数排序讲解

在讲解计数排序之前,我想先请大家思考这样一个问题:

    小A的班上只有5个人,他们的成绩分别是5分,2分,3分,5分,4分。请你将他们的成绩按从大到小的规则排序。

“我直接一个sort搞定收工”是不行的,请大家思考其它的做法

我们可以将这些分数分成不同的编号的旗子

定义一个大小为n的一维数组,也就是一堆从1到n的编号的桶子

我们需要将旗子和桶子一一对应,也就是将n号旗子放到n号桶子里面去。

最后计算每个桶子内旗子的数量一一输出。代码如下:

#include<bits/stdc++.h>
using namespace std;
int main(){
    int n, a[15] = {};//一定要将数组初始化为0,这是很多初学者都会犯的错误
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
        int tmp;
        scanf("%d", &tmp);
        a[tmp]++;//放进桶中
    }
    for (int i = 0; i <= 10; i++)//循环到每个可能出现的数都判断到
        while (a[i]) {
            printf("%d ", i);
            a[i]--;//输出了一次,还剩下的数量减一
        }
    return 0;
}

上面的代码就使用了计数排序的思想。

输入5 5 2 3 5 4时,桶内情况如下:

桶1(下标1)桶2(下标2)桶3(下标3)桶4(下标4)桶5(下标5)
011120

    其中,每个桶内的数量(即a[i])就可以看做考i分的同学的数量,这也是计数排序名称的由来。它还有两个好兄弟:桶排序基数排序,千万不要搞混了。我以前就把计数排序叫做桶排序。 刚入门就只需要学习最简单的计数排序就行了。

    桶排序有很多优点,比如时间复杂度只有 O ( n + w ) O(n+w) O(n+w)( w w w为值域,即要排序的数字最大是多少),访问某个数有多少快等。但它也有很多缺点,比如无法将名字等信息和数字一一对应,浪费空间(比如排序1 200001 198341 199999),无法排序负数和小数等。

    如果还想练习计数排序可以去看看洛谷 P7072 [CSP-J2020] 直播获奖,题解在这【题解】【排序】—— [CSP-J2020] 直播获奖

2.【深基9.例1】选举学生会

戳我查看题目(洛谷)

题目描述

学校正在选举学生会成员,有 n n n n ≤ 999 n\le 999 n999)名候选人,每名候选人编号分别从 1 1 1 n n n,现在收集到了 m m m m ≤ 2000000 m \le 2000000 m2000000)张选票,每张选票都写了一个候选人编号。现在想把这些堆积如山的选票按照投票数字从小到大排序。

输入格式

输入 n n n m m m 以及 m m m 个选票上的数字。

输出格式

求出排序后的选票编号。

输入输出样例

输入 #1

5 10
2 5 2 2 5 2 2 2 1 2

输出 #1

1 2 2 2 2 2 2 2 5 5

2.1.题意解析

    这道题我们可以直接模拟每个投票箱,已达到排序的效果,具体原理不再赘述。直接看代码。

2.2.AC代码

#include<bits/stdc++.h>
using namespace std;
#define MAXN 200010
int main()
{
    int n,m,tmp,a[MAXN]={},i;
    cin>>n>>m;
    for(i=1;i<=m;i++)//将数字放入桶里 
    {
    	cin>>tmp;
    	a[tmp]++;
	}
	for(i=1;i<=MAXN-10;i++)//每个桶都判断到,注意值最大为MAN-10
		while(a[i])//只要这个数字出现了
		{
			cout<<i<<' ';
			a[i]--;
		}
	return 0;
}

喜欢就订阅此专辑吧!

【蓝胖子编程教育简介】
蓝胖子编程教育,是一家面向青少年的编程教育平台。平台为全国青少年提供最专业的编程教育服务,包括提供最新最详细的编程相关资讯、最专业的竞赛指导、最合理的课程规划等。本平台利用趣味性和互动性强的教学方式,旨在激发孩子们对编程的兴趣,培养他们的逻辑思维能力和创造力,让孩子们在轻松愉快的氛围中掌握编程知识,为未来科技人才的培养奠定坚实基础。

欢迎扫码关注蓝胖子编程教育
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝胖子教编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值