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 fixed
n
为10。@Wolph我认为这可能有助于OP更好地理解流程:)