嘿所有,我现在正在考试,我似乎无法理解这个概念。 问题是,如果您给出了一系列学生记录,记录成员是学生姓名和成绩,您如何按年级对其进行排序。教授给出了他称之为“分布计数排序”的例子。我无法理解它,并希望有人可以给我下面的代码的伪代码或算法, 谢谢:))
Function Distribution_counting_sort(S, n){
//Input: a student array S of n records
//Output: a sorted array (wrt grade) NS
int count[101]; /*init to 0’s */
/* counting */
for (i = 0; i < n; i++) count[S[i].grade]++;
/* accumulating */
count[0]--;
for (i = 1; i < 101; i++) count[i] = count[i -1] + count[i];
/* distribution */
for (i = 0; i < n; i++) NS[count[S[i].grade]--] = S[i];
答案 0 :(得分:6)
这实际上是Bucket Sort的变体。
这些是桶,每个可能等级一个:
int count[101]; /*init to 0’s */
这可以计算每个年级的学生人数。这告诉我们每个桶的大小:
for (i = 0; i < n; i++) count[S[i].grade]++;
这会将计数转换为累积计数。这为我们提供了目标数组中每个存储桶的结束位置。我相信count[0]--
位是基于0的数组。
count[0]--;
for (i = 1; i < 101; i++) count[i] = count[i -1] + count[i];
现在它将每个学生放在他/她的桶的末尾,并递减该桶的位置值。
for (i = 0; i < n; i++) NS[count[S[i].grade]--] = S[i];
关于这种排序的好处是它是O(n),而不是O(n * log(n))。但它只适用于可以离散化为有限(且可管理)数量的桶的东西。
这个代码有点滑稽的一点是它颠倒了具有相同等级的学生的顺序。您可以通过将累积计数更改为存储桶起始位置并在填充NS时递增它们,或者更容易,在最后一个循环中向后遍历S来将其修改为稳定排序。
答案 1 :(得分:2)
共有101个等级,0 - 100
int count[101]; /*init to 0’s */
使用每个成绩的总计填充计数[],例如count [90] = 4表示四个人得到90%
for (i = 0; i < n; i++) count[S[i].grade]++;
接下来,将这些总数转换为正在运行的计数,即如果57人低于90,则计数[90] = 57 + 4或61.因此,对于每个计数[n],您有人数谁达到或低于该等级。这对于最终阵列很重要......在最终阵列中需要61个元素才能容纳90或更低的所有人。请注意,count [100]应该= n传入。
count [0] - 将整个计数向下移动一,将基于1的最终数组转换为基于0的最终数组,例如:如果我有一个人得到零,计数[0] = 1,那么我的最终数组将从NS [1]开始。我想从NS [0]开始。所以上面的61个元素现在是60
count[0]--;
for (i = 1; i < 101; i++) count[i] = count[i -1] + count[i];
最后(希望他不再重复'我'),找到每个年级的地方......如果有60个人有'90'或以下,等级'90'属于最后一个数组的第60个元素,NS。这很令人困惑,部分是因为' - '...记住,'90'等级有60,所以你来的第一个'90'将被放置在NS [60],因为有59成绩较低的人。 '90'的计数减少到59,所以下一个'90'将被放置在NS [59]。等等。
for (i = 0; i < n; i++) NS[count[S[i].grade]--] = S[i];
最终结果是最低等级到最高等级的阵列,NS [0]是最低等级,NS [n]是最高等级。
有意义吗?这真是一个很棒的算法!
答案 2 :(得分:0)
这篇关于排序的文章可能有所帮助。