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,看起来很好,但我不知道哪一个有更好的性能。
问题:
答案 0 :(得分:1)
您的代码似乎是正确的,它可以在排序数字时使用。但是,假设您有一组结构,您根据其键进行排序。在这种情况下,您的方法将不起作用,因为它只是计算数字的频率,而它保持正数则将其分配给输出数组中的增加索引。然而,经典方法适用于结构和对象等的数组,因为它计算每个元素应该去的位置,然后将数据从初始数组复制到输出数组。
回答你的问题:
1>是的,代码的运行时复杂性将是相同的,因为对于大小为n
且范围为0...k
的数组,您的内部和外部循环与f(0)+f(1)+...+f(k)
成比例,其中f表示频率为一个号码。因此运行时为O(n)。
2 - ;就渐近复杂性而言,两种方法都具有相同的性能。由于额外的循环,常数可能更高。但是,这也使得经典方法成为一种稳定的方法,并且具有我之前指出的好处。