计数排序是一种桶排序。我们假设我们正在使用它:
A
成为要排序的数组k
成为最大元素bucket[]
成为存储桶数组然后在伪代码中,计数排序看起来像这样:
Counting-Sort (A[], bucket[], k)
1. Init bucket[]
2. for i -> 1 to n
3. add A[i] to bucket[A[i].key].end
4. for i -> 1 to k
5. concatenate bucket[i].start to bucket[0].end
6. bucket[0].end=bucket[i].end
7. copy bucket[0] to A
时间线复杂度:
1)我知道在O(1)
中有一种方法(不简单但是一种方式)初始化数组2,3)O(n)
4,5)O(k)
6)O(n)
这为我们提供了O(k + n)的净运行时间,对于k>> n是Ω(n),这对我们不利。但是,如果我们可以改变第4,5行以某种方式跳过空桶呢?这样我们最终会得到O(n)no metter k是什么。
有谁知道怎么做?或者这是不可能的?
答案 0 :(得分:1)
一种选择是保持包含实际使用哪些桶的辅助BST。无论何时向存储桶添加内容,如果它是第一个放置在那里的条目,您还可以将该存储桶的值添加到BST。
当你想要连接所有内容时,你可以按排序顺序迭代BST,连接你找到的桶。
如果有实际使用的z桶,则需要O(n + z log z)。如果桶的数量与实际使用的数量相比较大,则可能会快得多。
更一般地说 - 如果你有办法对在O(f(z))时间内使用的z个不同的存储桶进行排序,你可以在O(n + f(z))时间内进行存储桶排序。维护实际使用的第二个数据桶阵列,在第一次使用时为数组添加一个存储桶。在迭代桶之前,在O(f(z))时间内对usem中的桶的索引进行排序然后遍历该数组以确定要访问的桶。例如,如果您使用了y-Fast树,则可以在O(n + z log log z)中进行排序。
希望这有帮助!
答案 1 :(得分:0)
您可以将存储桶数组转换为关联数组,从而产生O( n log n ),我不相信您可以做得更好排序(平均)。
在一般情况下,O( n )是不可能的。