Big o O(n)算法在计算时间上能超过O(n^2)吗?

Big o O(n)算法在计算时间上能超过O(n^2)吗?,big-o,complexity-theory,time-complexity,Big O,Complexity Theory,Time Complexity,假设我有两种算法: for(int i=0;i

假设我有两种算法:

for(int i=0;i
这自然是
O(n^2)
。假设我还有:

for(int i=0;i<100;i++){
对于(int j=0;j
这是
O(n)+O(n)+O(n)+O(n)+O(n)+。。。O(n)+=O(n)

看起来,即使我的第二个算法是
O(n)
,它也需要更长的时间。有人能详细介绍一下吗?我之所以提出这个问题,是因为我经常看到一些算法,比如说,它们会先执行一个排序步骤,或者类似的事情,当确定总的复杂度时,它只是限制算法的最复杂的元素

渐近复杂性(即大O和大θ表示的复杂性)完全忽略了所涉及的常数因子-它仅用于指示运行时间将如何随着输入大小的增大而变化

因此,对于某些给定的
n
,一个
n
算法可能比一个
n2
算法需要更长的时间,这当然是可能的-这将发生在
n
中,因为这将真正取决于所涉及的算法-对于您的特定示例,
n<100
就是这种情况,忽略两者之间不同的优化的可能性

对于分别使用
Θ(n)
Θ(n2)
时间的任意两个给定算法,您可能会看到:

  • n
    较小时,
    Θ(n)
    算法较慢,
    n
    增大时,
    Θ(n2)
    算法变慢
    (如果
    Θ(n)
    一个更复杂,即具有更高的常数因子,则会发生这种情况),或
  • Θ(n2)
    一个总是比较慢
虽然当然有可能
Θ(n)
算法会变慢,然后
Θ(n2)
1,然后
Θ(n)
再次变慢,以此类推,随着
n
的增加,直到
n
变得非常大,从这一点开始
Θ(n2)
1将始终变慢,虽然这不太可能发生

从数学角度来说: 假设
Θ(n2)
算法对一些
c
进行
cn2
运算

Θ(n)
算法对一些
d
进行
dn
运算

这与一致,因为我们可以假设
n
大于0(即,对于所有
n
),并且运行时间所在的两个函数是相同的

根据您的示例,如果您说
c=1
d=100
,那么
Θ(n)
算法将变慢,直到
n=100
,此时
Θ(n2)
算法将变慢

(由提供)

注: 从技术上讲,big-O只是一个上界,这意味着你可以说一个
O(1)
算法(或者任何需要
O(n2)
或更短时间的算法)也需要
O(n2)
。因此,我使用了大θ(Θ)符号,这只是一个紧界。有关更多信息,请参阅

Big-O通常被非正式地视为或被教导为紧束缚,因此您可能已经基本上在不知道的情况下使用了Big-Theta


如果我们只讨论一个上界(根据big-O的正式定义),那将是一个“万事俱备”的情况,
O(n)
一个可以更快,
O(n2)
一个可以更快,或者它们可以花费相同的时间(渐进地)-对于比较算法的大O,人们通常无法得出特别有意义的结论,我们只能说,给定某个算法的大O,该算法不会花费超过该时间量的时间(渐进)。

长话短说,是的,它可以。
O
的定义基于这样一个事实,即
O(f(x))
意味着
g(x)
在足够大的
x
的情况下,运行时间肯定比
f(x)
要长

例如,一个已知的事实是,对于小值,合并排序优于插入排序(如果我没记错的话,小于
31
n
应该是这样的)

Big
O(n)
并不意味着比较不同算法的相对速度。它们是用来测量输入量增加时运行时间增加的速度。比如说,

  • O(n)
    表示如果
    n
    乘以1000,则运行时间大致乘以1000
  • O(n^2)
    意味着如果
    n
    乘以1000,则运行大致乘以1000000
因此,当
n
足够大时,任何
O(n)
算法都将击败
O(n^2)
算法。这并不意味着对于固定的
n

是的,就运行时间而言,O(n)算法可以超过O(n2)算法。当常数因子(我们在大O表示法中省略)很大时,就会发生这种情况。例如,在上面的代码中,O(n)算法将有一个较大的常数因子。因此,它的性能比在O(n2)中运行n<10的算法差

这里,n=100是交叉点。因此,当一个任务可以同时在O(n)和O(n2)中执行,并且线性算法的常数因子大于二次算法的常数因子时,我们倾向于选择运行时间较差的算法。 例如,在对数组进行排序时,对于较小的数组,我们会切换到插入排序,即使合并排序或快速排序的运行速度逐渐加快。这是因为插入排序的常量因子小于合并/快速排序,并且运行速度更快。

是。
for (int i = 0; i < n; i++) {       (* A, the O(n*n) algorithm. *)
for (int i = 0; i < 100; i++) {     (* B, the O(n) algorithm. *)