为什么O(n ^ 2)算法变得越来越低效,它必须排序的项目量越大?

时间:2011-05-08 10:43:51

标签: algorithm

任何人都可以明确定义为什么O(n ^ 2)算法变得越来越低效,他们必须排序的项目越多?

E.g。冒泡排序 - 4096项需要24.56毫秒来排序,其中8192项需要98.56ms进行排序。任何人都可以清楚地解释为什么增长是如此?

9 个答案:

答案 0 :(得分:9)

这就是O(n ^ 2)函数的含义。

对于n项,你的算法有点像O(n ^ 2)。

(8192 ^ 2)/(4096 ^ 2)= 4即增长的2 ^ 2

和98.56 / 24.56 = 4.013 ..

答案 1 :(得分:5)

O(n²)在许多其他方面表示,对X元素进行排序所需的时间与对Y元素进行排序所需的时间之比约为X²/Y²(越接近X和Y接近无穷大)。

让我们计算:

8192² / 4096² = 2² = 4.00
98.56 / 24.56      ≈ 4.01

的确,你的排序是O(n²),这就是你应该期待的。

答案 2 :(得分:4)

严格来说,Big-O 不会告诉您实际使用的数字的增长情况。

Big-O表示法是关于极限内发生的事情,因为问题的大小(n)趋于无穷大。像4096和8192这样的特定小数字与big-O分类无关。此外,big-O是上限。冒泡排序为O(n ^ 2)。它也是O(n ^ 3),O(n ^ 27)和O(2 ^ n),因为所有这些函数也在极限运行时提供上限。尽管如此,上界非常宽松,但仍有界限。

在实践中,可以观察到您使用的许多或大多数算法的实际值n,以遵循与其“最佳”大O复杂性相对应的趋势。这就是你在这里看到的 - 将尺寸加倍使时间增加四倍,因为时间大约与n ^ 2成正比。因为时间与n ^ 2成比例,所以算法为O(n ^ 2)。相反的含义并不一定存在。

人们通常说“冒泡排序是O(n ^ 2)”,他们的意思是,“冒泡排序所需的时间与输入大小的平方成正比,忽略了一小部分特殊情况,这些情况要快得多(在冒泡排序的情况下已经排序的数据)“。这两种说法都是正确的,但后者并不是前者实际意味着什么,所以偶尔会让人感到困惑。这里的几个答案说的是同样的事情,就big-O的数学定义而言,它们也是错误的。但是不正确的用法是如此常见以至于它不能被忽略,大概是因为人们被非正式地引入到算法的大O分类而没有被教授正式的定义。

所以,当有人告诉你一个算法是O(n ^ 2)时,他们尝试告诉你的是它的最坏情况是Θ(n) ^ 2),如果是这样,他们可能会进一步试图告诉你,这种趋势是可以观察到的n你关心的那种。鉴于滥用符号,这就是为什么“O(n ^ 2)算法”在增加n时效率降低的原因。

答案 3 :(得分:2)

O表示上限,即函数的增长不会超过O()中定义的函数的增长。 对于某些f(x) = O (g(x))和某些常量|f(x)| <= C|g(x)|(称为见证人),x > k表示C。意味着对于某些Ck,如果我们绘制函数,那么所有点x > k g(x)对于每个x&gt;总是更大。 k,即g(x)定义上限。请注意,g(x)函数f(x)的值可能低于x<k的{​​{1}}。

这可以被认为是一辆以40千米每小时的速度行驶的汽车,另一辆汽车以0公里的速度行驶,但加速度有限。第一辆车没有任何增长,但由于第二辆车的增长速度大于第一辆车,我们可以看出,在某些时候,第二辆车的速度将超过第一辆车的速度。

答案 4 :(得分:2)

正如shevski和其他人所说,O(n2)算法根据定义具有行为。如果你真的认为你的数据已经被排序(复杂性降低到O(n)),那么冒泡排序是很方便的,这意味着大约每个元素都被循环通过而没有做任何事情。

我建议你查看维基百科并阅读Big O notationSorting algorithms;文章真的很可读。

对于符号本身,对于某些数据集和大小,O(n2)可以比O(n logn)算法更快,它取决于常量。即使不是更快,内存消耗也可能是分类大量数据集的一个因素。

与往常一样,最佳排序算法取决于数据和硬件(内存)的约束。虽然我敢说,冒险几乎没有办法实现。

如果您更喜欢动画,请查看here,您可以在其中看到 各种排序算法的工作原理。

答案 5 :(得分:2)

如果算法的运行时间 O(n 2 ,您可以直观地认为它意味着如果您增加 n 某些因素 k ,运行时间将增加因子 k 2

这意味着如果您将输入的大小加倍,算法运行的时间大约要长4倍。这与您遇到的时间一致。

答案 6 :(得分:1)

Big O和排序背后的理论有很多很好的答案,但我怀疑这不是你的关注。

一些算法(实际上大多数)在较大数据集中获得更多感染的原因很简单,因为每个添加的元素都必须与其余数据一起考虑。

如果您进行冒泡排序:如果您将一个元素添加到列表的末尾并对其进行排序,则可能必须遍历整个列表。这当然需要更长的清单。因此,每个元素的算法效率较低,添加的元素越多。

另一个O(n ^ 2)示例:假设您有n个点,并且对于每个点,您必须找到它最近的邻居。如果n = 10,则每个点必须进行9次比较=&gt; 9 * 10 = 90次比较。如果你加倍大小,n = 20,你将不得不进行19次比较。点。因此,算法对于每个点变得“效率低”。 =&GT; 19 * 20 = 380比较大约2 ^ 2 = 4倍。

答案 7 :(得分:0)

这完全取决于数据。对于冒泡排序O(n ^ 2)是最坏情况。如果您正在排序已排序的列表,它可以与O(n)一样好。

Generaly O()表示给定算法的最坏情况。

答案 8 :(得分:0)

对于冒泡排序,您只需要查看一个实现并计算有多少比较。然后我想你会明白的。