【发布时间】:2019-11-18 17:58:22
【问题描述】:
for (int i = 1; i <= max; i++)
{
c[i] = c[i] + c[i - 1];
}
这是代码,但我不明白为什么要累积元素的总和。
【问题讨论】:
-
我认为geeksforgeeks.org/counting-sort 可能会对您有所帮助。
标签: algorithm sorting counting-sort
for (int i = 1; i <= max; i++)
{
c[i] = c[i] + c[i - 1];
}
这是代码,但我不明白为什么要累积元素的总和。
【问题讨论】:
标签: algorithm sorting counting-sort
counting sort 算法用于对属于给定范围的元素序列进行排序。具体而言,假设我们正在对包含在区间[min, max] 中的自然数子集进行排序。
要理解算法,从我们想要获得的结果开始是很有用的。所以,让我们假设有序序列看起来像
m1, m1, m1, ..., m1, m2, m2,...,m2,.... m_l, m_l,..., m_l
|----------------| |-----------| |--------------|
k1 times k2 times k_l times
换句话说,我们的有序序列包含元素m1k1times,元素m2k2times等,还有m1 < m2 < ... < m_l。
如果你想为上面序列的每个元素分配一个位置索引,你会得到
index element
1 m1
2 m1
....
k1 m1
k1+1 m2
k1+2 m2
....
k1+k2 m2
....
k1+k2+...+k_(l-1)+1 m_l
k1+k2+...+k_(l-1)+2 m_l
....
k1+k2+...+k_(l-1)+k_l m_l
从这张表中可以看出,每个元素m_i(重复k_i 次)出现的索引从k1+...+k_(i-1)+1 到sum_i=k1+...+k_i,其中sum_i 是直到索引的频率之和i.
计数排序算法正是以这种方式工作的。
k_i)。通过[min,max] 范围,您可以获得一组max-min+1 频率(其中一些可能为零)。k_js 的部分总和sum_i,直到给定索引i
然后,为了输出排序后的序列,循环遍历索引,从 i=1 到 i=max-min+1。对于每个索引i 使得k_i > 0:
a) 您将m_i 的位置设置为sum_i
b) 将sum_i 减少 1
c) 重复 a) 和 b) 直到 sum_i==0
【讨论】:
计数排序算法分为三个步骤。您正在查看的是第 2 步。
这是完整的算法:
创建一个空的存储桶数组,对应于输入中的每个可能值(对于char 数组,这将是一个包含 256 个ints 的数组)。对于输入列表中的每个值,将存储在相应存储桶中的值递增。
将存储桶值转换为累计总数。
创建一个包含与输入列表一样多的元素的空数组。然后对于输入数组中的每个元素,递减该元素的累积总数,并使用结果值作为索引将该元素放入输出数组中。
最终结果是输出列表被输入列表的元素填充。
这是一个简短的工作示例(使用 0-9 的值):
Input: 2 5 4 5 8 4 5 9
Step 1:
Buckets: 0 0 1 0 2 3 0 0 1 1
Step 2:
Cumulative totals: 0 0 1 1 3 6 6 6 7 8
Step 3:
Cumulative totals Output list
Input value: 2 0 0 0 1 3 6 6 6 7 8 2 - - - - - - -
Input value: 5 0 0 0 1 3 5 6 6 7 8 2 - - - - 5 - -
Input value: 4 0 0 0 1 2 5 6 6 7 8 2 - 4 - - 5 - -
Input value: 5 0 0 0 1 2 4 6 6 7 8 2 - 4 - 5 5 - -
Input value: 8 0 0 0 1 2 4 6 6 6 8 2 - 4 - 5 5 8 -
Input value: 4 0 0 0 1 1 4 6 6 6 8 2 4 4 - 5 5 8 -
Input value: 5 0 0 0 1 1 3 6 6 6 8 2 4 4 5 5 5 8 -
Input value: 9 0 0 0 1 1 3 6 6 6 7 2 4 4 5 5 5 8 9
【讨论】: