我只是想计算某些程序片段的复杂度,但是我担心自己做的太简单了。如果我放下片段和答案,您能告诉我我做错了什么吗?
(a)
sum = 0;
for (i = 0;i < n;i++)
sum++;
答案:n,只有一个for循环
(b)
sum = 0;
for (i = 0;i < n;i++)
for (k = 0;k < n*n;k++)
sum++;
答案:因为嵌套循环,所以n ^ 2,尽管我想知道嵌套循环中的n * n是否使它成为n ^ 3
(c)
sum = 0;
for (i = 0;i < n;i++)
for (k = 0;k < i;k++)
sum++;
答案:n ^ 2
(d)
sum = 0;
for (i = 0;i < n;i++)
for (k = 0;k < i*i;k++)
sum++;
答案:n ^ 2,但我和b有同样的担忧
(e)
sum= 0;
for (i = 0;i < n;i++)
for (k = i;k < n;k++)
sum++;
答案:n ^ 2
答案 0 :(得分:0)
由于在您的所有示例中,主要操作都是sum++
,所以我们必须计算该基本操作的执行次数。
此外,在所有情况下,还有i++
和k++
也很重要。最后,必须在每个步骤将这些计数器与它们的限制进行比较,并且我们还应该考虑这些比较。现在,这些额外的操作不会更改迭代次数。它们只是使每次迭代变得更加昂贵。例如,
(a)
sum = 0;
for (i = 0;i < n;i++)
sum++;
重复n
次:i++
,sum++
和i<n
,所有这些都使3n
操作具有相似的复杂性。这就是总复杂度为O(n)
的原因。
一旦了解了这一点,就不再需要对复杂性进行详细分析,因为big-O表示法将处理这些额外的计算。
第二个例子
sum = 0;
for (i = 0;i < n;i++)
for (k = 0;k < n*n;k++)
sum++;
重复n
次操作
for (k = 0;k < n*n;k++)
sum++;
由于前一种情况,此操作的复杂度为O(n*n)
,因为这里的限制是n*n
而不是n
。因此,总复杂度为O(n*n*n)
。
第三个示例是相似的,只是这次执行的操作n
次是
for (k = 0;k < i;k++)
sum++;
,其复杂度随i
而变化。因此,我们不必将n
乘以n
,而是将不同的东西相加:
O(1) + O(2) + ... + O(n)
,由于O
中隐含的常数因子始终是相同的(=每个基本步骤要增加或比较的变量数),我们可以将其重写为
O(1 + 2 + ... + n) = O(n(n+1)/2) = O(n*n)
其他示例很相似,可以按照这些相同的想法进行分析。