为什么基数排序为O(nd)但合并排序不是O(d * nlogn)?

时间:2018-11-06 07:46:56

标签: algorithm sorting merge mergesort radix-sort

通常当人们谈论排序算法的复杂性时,我会看到以下解释:

  

基数排序的复杂度为O(nd),其中n是   列表,d是位数

  

合并排序的复杂度为O(n log n),其中n是合并长度   列表

这几乎是为了证明基数排序通常比合并排序要慢,即使这没有任何意义。

有两种情况:

情况1:。我们正在对具有四个字节的普通整数进行排序。 在这里,比较需要花费固定的时间,因此O(n log n)可以描述合并排序。但是,在对普通整数进行排序时,d中的O(nd)是一个常量(对于基数16来说可能是4,对于基数2来说可能是16,无论哪种方式,它都是常量,并且bin中的bin数是由基数排序比例调用的排序以对此进行补偿)。因此,说基数排序为O(n)并归并排序的客观复杂性在O(nlogn)上是否更有意义?

情况2::我们正在对字符串进行排序,可以将其视为基本ASCII中具有任意位数的数字。 在这里,比较需要花费O(d)时间,因为更糟糕的情况是将AAAAAAAABAAAAAAAAC进行比较可能会花费很长时间。 在这种情况下,说基数排序具有复杂性O(nd)是完全有意义的,因为d随输入而变化。 但是,由于比较时间不再是恒定的,在这种情况下合并排序是否也应被视为O(d*nlogn)呢?

在我看来,人们不相信基数排序足够快地使用,他们通过消除其复杂性描述,使其比基于比较的排序更糟糕,从而证明了它的大时间常数是合理的。

我为格式不正确表示歉意,我不确定如何使它在stackoverflow上看起来更好

1 个答案:

答案 0 :(得分:1)

比较逐字符(或逐数字)时的合并排序将是O(d n log n)个操作。但是您可以对任何类型的对象进行排序,并且比较可以是这些对象上的任何函数,因此这样的表示将过于具体-您需要其他一些复杂性才能使用不同的比较方法来表示相同的mergesort算法。

比较的数量来表示复杂性比较有意义,因此您可以说mergesort总是O(n log n)个比较。

通常也假定比较是一个非常快的操作,即恒定的时间(即使一般情况下不是这样)。另一方面,基数排序需要对每个数字的输入进行循环-您不能说有多少个循环都没关系。

比较mergesort和基数排序的复杂程度是在一定程度上比较了苹果和橘子。