C 为什么下面的嵌套循环O(n√;n)复杂?
我无法理解下面代码的复杂性。不过,我知道正确的答案。只是想知道为什么会这样C 为什么下面的嵌套循环O(n√;n)复杂?,c,for-loop,C,For Loop,我无法理解下面代码的复杂性。不过,我知道正确的答案。只是想知道为什么会这样 void main() { int i, j, n, x; for(i=0; i < n; i++) { for(j=0; j*j <= n; j++) { x=10; } } } void main() { int i,j,n,x; 对于(i=0;i
void main()
{
int i, j, n, x;
for(i=0; i < n; i++)
{
for(j=0; j*j <= n; j++)
{
x=10;
}
}
}
void main()
{
int i,j,n,x;
对于(i=0;i 对于(j=0;j*j外循环执行n
迭代
内部循环执行sqrt(n)
迭代(因为它将j
平方与n
进行比较)
循环体需要恒定的时间
将三者相乘得到O(n sqrt(n))
另外,一个好的编译器可能会为这个精确的循环生成
O(1)
代码。画一张表,你就会知道为什么。假设n=10
:
i | j
-----+-----
0 | 0 0*0 <= 10 ? Yes | |
0 | 1 1*1 <= 10 ? Yes | |
0 | 2 2*2 <= 10 ? Yes | → O(√n) Times |
0 | 3 3*3 <= 10 ? Yes | |
0 | 4 4*4 <= 10 ? NO! | |
1 | 0 ... |
1 | 1 | → O(n) Times
.. | .. |
.. | .. |
9 | 0 |
9 | 1 |
9 | 2 |
9 | 3 |
9 | 4 |
i|j
-----+-----
0 | 0 0*0第一个循环可以从1变为n,第二个循环可以从1变为sqrt(n)。。
这就是复杂性为O(n*sqrt(n))的原因。外部循环为O(n)-执行时间与元素数量成正比
但是它有一个内循环,在外循环的每次迭代中执行一次。当执行次数的平方等于n时,这个循环停止。也就是说,它执行√外循环每次迭代n次
因此,总复杂度为O(nx)√n) ,写为O(n)√n) .使用西格玛表示法,您可以获得精确的迭代次数加上增长复杂性的顺序(经经验验证):
您如何总结这里的sqrt(n)
?两个循环都从0运行到n
,并且n
没有被修改。@Wolph:终端条件不同(一个使用i
,另一个使用j
的平方)。如果我们忽略n没有初始化为一个值。因为x总是变成10,一个好的编译器只需删除循环并直接将x设置为10,这样就没有复杂性。@Johan Emmm…没有“无复杂性”这类东西。它被称为O(1)@Johan即使是一个好的编译器,如果使用-O0
:-)执行,也不应该这样做甚至不需要赋值x
,因为它是一个局部变量。该程序没有明显的副作用。为了这个例子,你从哪里得到4*4@Wolph I fixedn
为10。@Wolph我认为这可能有助于OP更好地理解流程:)