有没有办法在铲斗排序时跳过空桶?

时间:2011-08-31 22:33:49

标签: algorithm sorting time-complexity bucket

计数排序是一种桶排序。我们假设我们正在使用它:

  • 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是什么。

有谁知道怎么做?或者这是不可能的?

2 个答案:

答案 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 )是不可能的。