通常当人们谈论排序算法的复杂性时,我会看到以下解释:
基数排序的复杂度为
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)
时间,因为更糟糕的情况是将AAAAAAAAB
与AAAAAAAAC
进行比较可能会花费很长时间。
在这种情况下,说基数排序具有复杂性O(nd)
是完全有意义的,因为d
随输入而变化。
但是,由于比较时间不再是恒定的,在这种情况下合并排序是否也应被视为O(d*nlogn)
呢?
在我看来,人们不相信基数排序足够快地使用,他们通过消除其复杂性描述,使其比基于比较的排序更糟糕,从而证明了它的大时间常数是合理的。
我为格式不正确表示歉意,我不确定如何使它在stackoverflow上看起来更好
答案 0 :(得分:1)
比较逐字符(或逐数字)时的合并排序将是O(d n log n)
个操作。但是您可以对任何类型的对象进行排序,并且比较可以是这些对象上的任何函数,因此这样的表示将过于具体-您需要其他一些复杂性才能使用不同的比较方法来表示相同的mergesort算法。>
用比较的数量来表示复杂性比较有意义,因此您可以说mergesort总是O(n log n)
个比较。
通常也假定比较是一个非常快的操作,即恒定的时间(即使一般情况下不是这样)。另一方面,基数排序需要对每个数字的输入进行循环-您不能说有多少个循环都没关系。
比较mergesort和基数排序的复杂程度是在一定程度上比较了苹果和橘子。