这似乎是一本非常普通的书(Cormen,Leiserson,Rivest,Stein),所以希望有人能够提供帮助。在第8章中,给出了计数排序的算法。在有输入数组A的地方有意义,你会发现数组C的大小从0到k的范围。然后使C [i]包含A中等于i的元素数。例如:
A: [2,5,3,0,2,3,0,3]
C: [2,0,2,3,0,1]
但是在此之后,它们使得C [i]包含小于或等于i的元素数。例如:
C: [2,2,4,7,7,8]
为什么这有必要?难道你不能只遍历原始的C并从那里得到一个排序的数组?你知道每个数字的确切数量,所以你可以按顺序将每个数字的正确数量放在B中,并有一个排序的数组。是否将C从第一种形式转换为第二种形式以某种方式使其稳定?
答案 0 :(得分:4)
我想您建议使用中间C
(使用索引1数组)执行以下操作:
i = 1
for k = 1 to len(C)
for j = 1 to C[i]
B[i] = k
i = i + 1
这似乎是合理的,并且具有相同的渐近运行时间。但是,请考虑这样一种情况,即您要对其键进行排序的项不仅仅是单个整数,而且还附加了一些其他数据。计数算法使排序稳定;保留具有相同键的项目的相对顺序(请参阅the Wikipedia article)。如果只分配C
索引的输出,则无法对常规数据进行排序。因此,为什么排序通过B[C[A[j]]] <- A[j]
分配元素。
对于其他好奇的人来说,这是原始算法的完成:
# C[i] now contains the number of elements equal to i.
for i = 1 to k
C[i] <- C[i] + C[i-1]
# C[i] now contains the number of elements less than or equal to i.
for j = length[A] downto 1
B[C[A[j]]] <- A[j]
C[A[j]] <- C[A[j]] - 1
为了解释最后一部分的减量,我引用了这本书,这也解释了这种稳定性:
因为元素可能不相同,所以每次将值
C[A[j]]
放入A[j]
数组时,我们都会递减B
。递减C[A[j]]
会导致下一个输入元素的值等于A[j]
,如果存在,则转到输出数组中A[j]
之前的位置。
另外,如果我们这样做,我想我们将不能再称它为COUNTING-SORT
,因为它不会计算少于输入数组中任何特定项目的项目数量(因为它们定义它)。 :)