计算从简介到算法的排序的奇怪步骤

时间:2013-02-21 05:50:14

标签: algorithm sorting

这似乎是一本非常普通的书(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从第一种形式转换为第二种形式以某种方式使其稳定?

1 个答案:

答案 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,因为它不会计算少于输入数组中任何特定项目的项目数量(因为它们定义它)。 :)