O(n log n)算法总是优于所有O(n ^ 2)算法吗?

时间:2018-05-27 21:15:49

标签: algorithm time-complexity big-o

在尝试正确理解Big-O时,我想知道O(n log n)算法是否始终优于所有 O(n^2)算法。

是否有O(n^2)会更好的特殊情况?

我已多次阅读,例如,在排序中,当数据几乎排序时,像气泡排序这样的O(n^2)算法会特别快,因此它会比O(n log n)算法更快,例如合并排序,在这种情况下?

4 个答案:

答案 0 :(得分:1)

O(n log n)优于O(n 2 渐近

Big-O,Big-Theta,Big-Omega,所有这些都衡量函数的渐近行为,即函数在其参数达到某个极限时的行为方式。

O(n log n)函数比O(n 2 )函数生长得慢,这就是Big-O符号本质上所说的。但是,这并不意味着O(n log n)总是更快。它只是意味着在某些时候,对于不断上升的n值,O(n log n)函数总是更便宜。

Big O

在该图像中,f(n)= O(g(n))。注意,有一个范围,其中f(n)实际上比g(n)更昂贵,即使它是由g(n)渐近限制的。然而,当谈到限制或渐近的时候,从长远来看,f(n)优于g(n)""所以说。

答案 1 :(得分:1)

不,O(n log n)算法并不总是优于O(n^2)算法。 Big-O表示法描述算法的渐近行为的上限,即对于倾向于无穷大的n。

在此定义中,您必须考虑以下几个方面:

  1. Big-O表示法是算法复杂度的上限,这意味着对于某些输入(如您提到的关于排序算法的输入),具有最差Big-O复杂度的算法实际上可能表现更好(冒泡排序运行在{ {1}}表示已排序的数组,而mergesort和quicksort始终至少O(n)};
  2. Big-O表示法仅描述了复杂性类别,隐藏了在实际情况下可能相关的所有常数因子。例如,对于小于2000000的输入,类O(n log n)中具有复杂度1000000 x的算法比具有复杂度O(n)(类0.5 x^2)的算法执行得最差。基本上, Big-O表示法告诉您,对于足够大的输入n,O(n^2)算法的效果优于O(n),但如果使用小输入,您可能仍然更喜欢后一种解决方案。

答案 2 :(得分:0)

除了@ cadaniluk的回答:

如果将算法的输入限制为非常特殊的类型,这也会影响运行时间。例如。如果仅在已排序的列表上运行排序算法,BubbleSort将以线性时间运行,但MergeSort仍需要O(n log n)。 还有一些算法具有糟糕的最坏情况复杂性,但具有良好的平均情况复杂性。这意味着存在错误的输入实例,使得算法很慢,但总的来说,您不太可能遇到这种情况。

也永远不要忘记,Big-O表示法隐藏了较低阶的常量和附加函数。因此,具有最坏情况复杂度O(n log n)的算法实际上可能具有2 ^ 10000 * n * log n的复杂度,并且您的O(n ^ 2)算法实际上可以在1/2 ^ 1000 n ^ 2中运行。因此对于n< 2 ^ 10000你真的想要使用"更慢"算法

答案 3 :(得分:0)

这是一个实际的例子。 排序函数的GCC实现具有O(n log n)复杂度。然而,一旦被分类的部分的大小小于某个小常数,它们就采用O(n ^ 2)算法。 这是因为对于小尺寸,它们在实践中往往更快。

See here用于某些内部实施。