在尝试正确理解Big-O时,我想知道O(n log n)
算法是否始终优于所有 O(n^2)
算法。
是否有O(n^2)
会更好的特殊情况?
我已多次阅读,例如,在排序中,当数据几乎排序时,像气泡排序这样的O(n^2)
算法会特别快,因此它会比O(n log n)
算法更快,例如合并排序,在这种情况下?
答案 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)函数总是更便宜。
在该图像中,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。
在此定义中,您必须考虑以下几个方面:
O(n)
}; 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用于某些内部实施。