题目
分析
本题进入“排序”部分,并引入了第一种排序方式:计数排序。
计数排序的好处是无需真正排序(也就是说,不存在比较的操作),而是只更新元素对应的“槽”(票箱、木桶)中的计数——也因此,要求元素与“槽”的位置有明确的对应。在本题中,候选人用“号数”代表(1-n),正好可以用数组的1-n号索引对应。
注意,这也是使用计数排序的核心!
计数排序有两部分:
读入元素,更新计数
因为所有m个投票必然有对应的“候选人”(票箱),所以,可以直接读入,然后更新对应“候选人票箱”(也就是第几号票箱)的票数:
for (int i = 1; i <= m; i++)
{
int who;
cin >> who;
votes[who]++;
}
按序输出
由于数组的索引本身就是有序的,我们已经获得了一个排序,但本题中要输出各个候选人的票数——也就是数组每个位置的值:
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= votes[i]; j++)
{
cout << i << " ";
}
}
答案

思考
计数排序看似简明,但有一些限制。
首先,为了计数而开设的数组是很稀疏的。它的大小取决于要排序的数值的范围,但最终被赋值(有计数)的数组取决于m(本题是投票数量),如果数值范围很大而投票数量较小,就会造成计数数组中有大量元素是0。另外,它也不能简单地对浮点数、字符串或者复杂一些的数据结构排序。
