繁体   English   中英

如何找到while循环的时间复杂度(Big O)?

[英]How do I find the time complexity (Big O) of while loop?

代码 1

int i = 0;
int j = 0;
while(i < n){
     while(j < n){
        printf("{%d,%d}",arr[i],arr[j]);
        j++;
    }
    i++;
    j = 0;
    printf("\n");
}

代码 2

int result = 0;
int i = 0;
while (i < n / 2){
    result += arr[i];
    i += 1;
    while (i >= n / 2 && i < n){
        result += arr[i];
        i += 1;
    }
}
printf("%d\n", result);

我只知道如何使用 for 循环找到时间复杂度,但我不确定 while 循环。 如果有人能帮我找到每个代码的总运行时间,将不胜感激。

第一个代码示例几乎是 for 循环的分类。 它的复杂度是 O(n^2)。 这是因为内部循环的复杂度为 O(n) 并且它运行了 n 次。

第二个有点困难,直到你看到它相当于一个非嵌套循环(忽略检查的复杂性)

int result = 0;
int i = 0;
while (i < n){
    result += arr[i];
    i += 1;
}
printf("%d\n", result);

意味着它的复杂度是 O(n)

计算时间复杂度的最佳方法是尝试真正了解算法的工作原理并计算操作数。 在第二个示例中,在外循环进行最后一次迭代之前,内循环永远不会运行。 而且由于它们甚至执行相同的代码,因此整个过程可以减少为一个循环。

另一个很好的例子是这样的:

for(i=0;i<n;i++){
    for(j=i;j<n;i++){
        //do something
    }
}

让我们计算一下操作:1 + 2 + 3 + 4 + ... + n。 这归结为 n*n/2 导致 O(n^2)

一个 for 循环,归根结底是一个 while 循环。 形式的东西:

for(int i=0; i<n; i++)

相当于:

int i=0;

while(i<n)
{
 i++;
}

事实上,在算法的纯数学分析中,您应该在算法中将任何 for 循环转换为 while 循环(有几个原因)。

回到你的代码。 分析很简单:

  • 在 while 循环的第一次迭代之前,i 的值为 0。
  • 存在更新变量 i (i++) 的唯一语句。
  • 在外循环的每次迭代中,i 增加 1。
  • 外循环最多运行 n 次。

  • 在任何循环的迭代之前,j 的值为 0。

  • 有 2 条语句更新 j(j=0 和 j++)
  • 非正式地:我们可以在内循环的任何迭代之前知道 j 的值是 0。

  • 在内部循环中,更新 j 的唯一语句是 j++。

  • 在内部循环的每次迭代中,j 增加 1。
  • 内部循环最多由循环保护运行 n 次。

  • 对于外循环的每次迭代,外循环最多运行 n 次,内循环最多运行 n 次。 所有其他语句都是不变的。 算法在 O(n*n)=O(n^2)

第二个稍微复杂一些,但是:

  • 在外循环的第一次迭代之前,i 的值为 0。
  • 非正式地:外循环将运行直到 i 的值为 (n/2 - 1)
  • 更新语句 (i += 1) 将 i 更新为 (n/2)
  • 非正式地:内循环运行 (nn/2 = n/2) 次并且它只运行一次。 - 外循环运行 n/2 次,内循环运行 n/2 次正好一次。

该算法因此运行 O(n/2+n/2) = O(n) 次

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM