为什么O(n ^ 2)算法在同一输入上比O(n)算法运行得更快?

时间:2013-04-14 08:13:06

标签: algorithm sorting

两种算法说A和B都是为了解决同样的问题而编写的。 算法A是O(n)。 算法B是(n ^ 2)。 您希望算法A更好地工作。

但是,当您运行同一台计算机的特定示例时,算法B运行得更快。 给出理由解释这样的事情是怎么发生的?

5 个答案:

答案 0 :(得分:22)

例如,

算法A可以在时间10000000*n中运行,O(n) 如果算法B在n*n中运行O(n^2),则每n < 10000000的A都会变慢。

O(n), O(n^2)是渐近运行时,用于描述n->infinity

时的行为

编辑 - 示例

假设您有以下两个功能:

boolean flag;

void algoA(int n) {
  for (int i = 0; i < n; i++)
    for (int j = 0; j < 1000000; j++)
      flag = !flag;

void algoB(int n) {
  for (int i = 0; i < n; i++)
    for (int j = 0; j < n; j++)
      flag = !flag;

algoA标记了n*1000000个标记翻转操作,因此它是O(n)algoB标记了n^2标记翻转操作,因此它是O(n^2)

只需解决不等式1000000n > n^2,就可以得到它所拥有的n < 1000000。也就是说,O(n)方法会更慢。

答案 1 :(得分:3)

Big-O-notation对速度本身一无所知,只是关于当你改变n时速度如何变化。

如果两次算法在一次迭代中花费的时间相同,那么@ Itay的例子也是正确的。

答案 2 :(得分:3)

了解算法有助于提供更准确的答案。

但就一般情况而言,我可以想到一些相关因素:

  • 硬件相关

    e.g。如果较慢的算法充分利用缓存和局部性或类似的低级机制(参见Quicksort的性能与其他理论上更快的排序算法相比)。值得一读的是timsort,作为一个例子,使用“高效”算法将问题分解为较小的输入集,并在这些集合中使用“更简单”和理论上“更高复杂度”的算法,因为它更快

  • 输入集的属性

    e.g。如果输入尺寸很小,测试效率就不会达到;另外,例如再次排序,如果输入主要是预先排序而非完全随机,您将看到不同的结果。在此类测试中应使用许多不同的输入以获得准确的结果。仅使用一个示例是不够的,因为可以将输入设计为支持一种算法而不是另一种算法。

  • 任一算法的具体实施

    e.g。从算法的理论描述到实现还有很长的路要走;数据结构使用不当,递归,内存管理等会严重影响性能

答案 3 :(得分:2)

虽然到目前为止所有的答案看起来都是正确的......但在CS类的背景下,他们都没有感到真正的“正确”。在计算复杂性课程中,您希望精确并使用定义。我将概述这个问题的很多细微差别和一般的计算复杂性。最后,我们将总结为什么Itay在顶部的解决方案可能就是你应该写的。我对Itay解决方案的主要问题是缺乏定义,这对于为CS类编写好的证据至关重要。请注意,我的定义可能与您的课程略有不同,因此请随意替换您想要的内容。

当我们说“算法是O(n)”时,我们实际上意味着“此算法在集O(n)”中。并且集合O(n)包含所有算法,其最坏情况渐近复杂度f(n)具有f(n) <= c*n + c_0对于某些常量c和{{1}的属性其中c_0

现在我们要证明你的主张。首先,你陈述问题的方式,它有一个简单的解决方案。那是因为我们的渐近界是“最坏情况”。对于许多“慢”算法,某些输入可以非常快速地运行。例如,如果输入已经排序,则插入排序是线性的!因此,请插入排序(c, c_0 > 0)并合并排序(O(n)),并注意如果传入已排序的数组,插入排序将运行得更快!热潮,证明完成。

但我认为你的考试意味着更像“为什么线性算法在最坏的情况下可能比二次算法运行得更快”。正如亚历克斯上面提到的,这是一个开放式问题。问题的关键在于运行时分析假设某些操作是O(nlog(n)) (例如,对于某些问题,您可能会假设乘法为O(1),即使它变为二次方变慢大数(有人可能会争辩说,给定问题的数字被限制为100位,所以它仍然是“恒定时间”))。由于您的课程可能专注于计算复杂性,因此他们可能希望您掩盖这个问题。因此,我们将假设我们的O(1)假设是正确的来证明索赔,因此没有像“缓存使这种算法比另一种算法更快”的细节。

现在我们有一个在O(1)中运行的算法f(n)以及在O(n)中运行的其他算法g(n)。我们想要使用上面的定义来表明,对于某些O(n^2),我们可以n。诀窍是我们的假设没有修复g(n) < f(n)。正如Itay所提到的,我们可以为这些常量选择值,对于许多c, c_0, c', c_0'来说g(n) < f(n)。其余的证据就是他上面所写的内容(例如,让n成为c, c_0的常数,并说它们都是100,而f(n)c', c_0'的常量,他们都是1.然后g(n)

答案 4 :(得分:1)

这取决于不同的场景。场景有三种类型1.Best,2.Average,3.Worst。如果您了解排序技术,也会发生相同的事情。有关更多信息,请参阅以下链接:

http://en.wikipedia.org/wiki/Sorting_algorithm

如果我错了,请纠正我。