算法的大O表示法

时间:2014-02-21 13:59:14

标签: c++ algorithm big-o time-complexity analysis

我正忙着做作业,我正在努力解决一个问题。我知道我不应该直接询问作业问题,所以我理解我是不是直截了当的答案。但无论如何这里仍然存在。

我们必须计算不同算法的运行时复杂度,我坚持的就是这个。

for(int i = 1 ; i < n ; i++)
    for(int j = 0 ; j < i ; j +=2)
        sum++;

根据我的理解,我的第一个想法是小于O(n 2 ),因为嵌套循环没有运行n次,而j变量仍然增加2每个循环而不是像正常循环那样迭代。虽然,当我做了一些N = 10,N = 100,N = 1000等的代码模拟时,我在输出sum变量时得到了以下结果。

N = 10 : 25, 
N = 100 : 2500,
N = 1000 : 250000,
N = 10000 : 25000000

当我查看这些结果时,O符号似乎应该比O(n)大得多。

我们在赋值中给出的4个选项是:O(1),O(n 2 ),O(n)和O(logn)。正如我之前所说,我看不出它如何像O(n 2 )一样大,但结果却指向了这一点。所以我只是觉得我不完全理解这一点,或者我错过了一些链接。

任何帮助将不胜感激!

6 个答案:

答案 0 :(得分:11)

Big O表示法不会为您提供操作数量。它只是告诉你它随着输入的增长会有多快。这就是你观察到的。

当您增加输入c次时,操作总数会增加c^2

如果您精确计算(几乎)精确的操作次数,您将获得(n^2)/4

当然你可以用总和来计算它,但是由于我不知道如何使用数学,所以我会给出一个“经验”的解释。具有相同开始和结束条件的简单循环内循环给出n^2。这样的循环产生"i""j"的所有可能组合的矩阵。因此,如果两个案例中的结果为1且结尾为N,则会获得N*N个组合(或有效迭代)。

但是,你的内循环适用于i < j。这基本上是在这个正方形中形成一个三角形,即第一个0.5因子,然后你跳过其他所有元素,这是另一个0.5因子;乘以你得到1/4。

O(0.25 * n^2) = O(n^2)。有时人们喜欢将因子留在那里因为它可以让你比较具有相同复杂性的两种算法。但它并没有改变n的增长率。

答案 1 :(得分:2)

请记住,big-O是渐近符号。常量(加法或乘法)对其有零影响

因此,外循环运行n次,并且在i时,内循环运行i / 2次。如果它不是/ 2部分,则它将是所有数字1 .. n的总和,这是众所周知的n * (n + 1) / 2。对于非零a * n^2 + b * n + c,它会扩展为a,因此它是O(n^2)

我们不是总结n个数字,而是汇总n / 2个数字。但那仍然在(n/2) * ((n/2) + 1) / 2左右。对于非零d * n^2 + e * n + f,其仍会扩展为d,因此它仍为O(n^2)

答案 2 :(得分:1)

从您的输出中看起来像: sum~ =(n ^ 2)/ 4。

这显然是O(n ^ 2)(实际上你可以用teta替换O)。 您应该回想一下Big-O表示法的定义。请参阅http://en.wikipedia.org/wiki/Big_O_notation

答案 3 :(得分:1)

事情是,n的平方上的操作数量依赖,即使总数小于n²。然而, scaling 对于Big-O表示法很重要,因此它是O(n²)

答案 4 :(得分:0)

使用:

for (int i = 1 ; i < n ; i++)
    for (int j = 0 ; j < i ; j +=2)
        sum++;

我们有:

0+2+4+6+...+2N == 2 * (0+1+2+3+...+N) == 2 * (N * (N+1) / 2) == N * (N+1)

所以,对于n == 2N,我们(n / 2) * (n / 2 + 1)〜= (n * n) / 4

所以O(n²)

答案 5 :(得分:0)

你对时间复杂度的理解是不合适的。时间复杂性不仅仅是'sum'变量的问题.um'只计算内循环迭代的次数,但你还必须考虑外循环迭代的总数

现在考虑你的计划:

 for(int i = 1 ; i < n ; i++)
    for(int j = 0 ; j < i ; j +=2)
        sum++;

时间复杂度意味着程序相对于输入值的运行时间(此处为n)。运行时间并不意味着在计算机中执行程序所需的实际时间。实际所需时间因机器而异。所以要获得机器独立运行时,Big O表示法非常有用.Bog O实际上来自数学,它用数学函数描述运行时间。

外循环执行总共(n-1)次。对于这些(n-1)值中的每一个(从i = 1开始),内循环迭代i / 2次。内循环迭代的总数= 1 + 1 + 2 + 2 + 3 + 3 + ... +(N / 2)+(N / 2)= 2(1 + 2 + 3 + ... + N / 2)= 2 *(N / 2(N / 2 + 1))/ 2 = N ^ 2/4 + N / 2。 类似地,'sum ++'也执行总n ^ 2/4 + n / 2次。现在考虑程序的第1行的成本= c1,第2行的成本= c2和第3行的成本= c3。这些演员可以是不同的不同的机器。所以执行程序所需的总时间= c1 *(n-1)+ c2 *(n ^ 2/4 + n / 2)+ c3 *(n ^ 2/4 + n / 2)=(c2 + c3) n ^ 2/4 +(c2 + c3)n / 2 + c1 * n-c1。因此所需的时间可以用数学函数表示。在Big O表示法中你可以说它是O((c2 + c3) n ^ 2/4 +(c2 + c3)n / 2 + c1 * n-c1)。在Big O表示法的情况下,可以忽略低阶项和最高阶项的系数。因为对于n的大值,n ^ 2远大于n。所以你可以说它是O((c1 + c2)n ^ 2/4)。同样对于n的任何值,n ^ 2大于(c1 + c2)n ^ 2/4的常数因子,所以你可以说它是O(n ^ 2)。