关于计数排序算法

时间:2010-06-19 15:34:16

标签: algorithm analysis

我读过一个计数排序算法,如下所示:

Counting Sort(A[1,..n]) //C[1,...k] is the temporary memory and k is the range of integers
   for  i<-- 1 to k
      C[i]<-- 0
   for  j<-- 1 to n
      C[A[j]]<--C[A[j]]+1
   for  i<--2 to k
      C[i]<--C[i]+C[i-1]
   for  j<--n downto 1
      B[C[A[j]]]<--A[j]
      C[A[j]]<--C[A[j]]-1

我想知道,如果我将最后一个更改为:for j<--1 to n,算法也将是正确的???(有没有办法证明这个“for”算法将是正确的???)

这样算法也是稳定的吗?

感谢

4 个答案:

答案 0 :(得分:4)

算法两种方式都是正确的。它现在也很稳定。

如果您将上一个for更改为您所说的内容,它将会停止稳定。

基本上,C[i] = how many elements <= i exist在第三个for循环结束后。因此,C[A[j]]会按排序顺序为您提供值为A[j]的元素的最后位置,C[A[j]] - 1 倒数第二个位置值为A[j]的元素,依此类推。这就是你减少C中值的原因。

因此,如果您关心稳定性,则必须以相反的顺序开始迭代原始数组:以便原始数组中具有值x的最后一个元素首先放入新数组中。反向迭代原始数组将保证x在所有其他值等于x之后,从而使算法稳定。

答案 1 :(得分:2)

好的,简短解释算法:

  1. for循环:用0和大小k(整数范围)初始化C数组
  2. for循环:计算整数并将数字存储在C
  3. for循环:总结与给定值不相等的值的总数 示例:有五个1,三个2,两个3 =&gt; c [1] = 5,c [2] = 8,c [3] = 10
  4. for循环:从A数组的末尾开始,并将其放入B值中的相应C值并减小C中的值
  5. 因为您在C数组中存储了不同数字的最后位置,所以您也必须在A数组的末尾开始。如果您只使用整数,那么如果从j < - 1到n

    开始,算法也是正确的 没有给出稳定性:例如1s将按逆序

    示例:(我添加了一次索引,两次显示顺序)

    A [1a,2,1b]

    首先进行循环

    • C [1] = 0
    • C [2] = 0

    第二个循环

    j = 1:A [1] = 1a

    C[1] = 1
    C[2] = 0
    

    j = 2:A [2] = 2

    C[1] = 1
    C[2] = 1
    

    j = 3:A [3] = 1b

    C[1] = 2
    C[2] = 1
    

    第三个循环

    C [2] = 3

    第四个循环

    J =      B [2] = 1A      C [1] = 1

    J = 2     B [3] = 2     C [2] = 2

    J = 3     B [1] = 1b的     C [1] = 0

    由于:

    • b [1] = 1b
    • b [2] = 1a
    • b [3] = 2

    =&GT;不稳定

答案 2 :(得分:0)

这个算法对我来说似乎很稳定。

如果您更改了上一个for,那么它仍然是正确的,但不会稳定。 (将颠倒相等元素的顺序)。

答案 3 :(得分:0)

是的,1 to n仍会正确排序,但您会使用n downto 1的稳定性。

在第二个循环C包含推理总和之后,这些值恰好是最终数组中每个数字的 last 元素的标记。这就是为什么倒退会带来稳定性。

您也可以获得1 to n的稳定性:

Counting Sort(A[1,..n]) //C[1,...k] is the temporary memory and k is the range of integers
   for  i<-- 1 to k
      C[i]<-- 0
   for  j<-- 1 to n
      C[A[j]]<--C[A[j]]+1
   last <-- C[1]
   C[1] <-- 0
   for  i<--2 to k
      tmp <-- C[i]
      C[i]<--C[i-1]+last
      last <-- tmp
   for  j<--n downto 1
      B[C[A[j]]]<--A[j]
      C[A[j]]<--C[A[j]]-1

累积金额有点难看。但我相信这可以做得更好。