计数排序的性能

时间:2013-08-27 09:46:28

标签: algorithm sorting complexity-theory

AFAIK counting sort正在使用以下算法:

// A: input array
// B: output array
// C: counting array
sort(A,B,n,k)
1. for(i:k) C[i]=0;
2. for(i:n) ++C[A[i]];
3. for(i:k) C[i]+=C[i-1];
4. for(i:n-1..0) { B[C[A[i]]-1]=A[i]; --C[A[i]]; }

我删除第3步和第4步,然后执行以下操作?

3. t=0; for(i:k) while(C[A[i]]) { --A[i]; B[t++]=i; }

完整代码here,看起来很好,但我不知道哪一个有更好的性能。

问题:

  1. 我猜这两个版本的复杂性是一样的,是真的吗?
  2. 在步骤3和步骤4中,第一个版本需要迭代n + k次,第二个版本只需要迭代n次。那么第二个有更好的表现吗?

1 个答案:

答案 0 :(得分:1)

您的代码似乎是正确的,它可以在排序数字时使用。但是,假设您有一组结构,您根据其键进行排序。在这种情况下,您的方法将不起作用,因为它只是计算数字的频率,而它保持正数则将其分配给输出数组中的增加索引。然而,经典方法适用于结构和对象等的数组,因为它计算每个元素应该去的位置,然后将数据从初始数组复制到输出数组。

回答你的问题:

1>是的,代码的运行时复杂性将是相同的,因为对于大小为n且范围为0...k的数组,您的内部和外部循环与f(0)+f(1)+...+f(k)成比例,其中f表示频率为一个号码。因此运行时为O(n)。

2 - ;就渐近复杂性而言,两种方法都具有相同的性能。由于额外的循环,常数可能更高。但是,这也使得经典方法成为一种稳定的方法,并且具有我之前指出的好处。