这个循环的大O是什么?

时间:2017-12-10 03:02:36

标签: c++ loops time-complexity big-o asymptotic-complexity

作为初学程序员,我总是很难注意到有时简单代码的复杂性。有问题的代码是:

k = 1;
while (k <= n){
    cout << k << endl;
    k = k * 2;
}

起初,由于k = k * 2线,我认为复杂度为O(log n),我将代码作为测试运行并跟踪它在n的大小上循环的次数,即使是大尺寸的n也相对较低。我也很确定它不是O(n),因为它可能需要更长的时间来运行,但我可能在那里错了,因为这就是我提出这个问题的原因。

谢谢!

4 个答案:

答案 0 :(得分:2)

是O(log n)。 每次迭代,k加倍 - 这意味着在(log n)次迭代中它将等于或大于n。

答案 1 :(得分:2)

在你的例子中,k不会增加1(k ++),它每次运行时都会加倍,并在log(n)时间内遍历循环。请记住,对数是取幂的相反操作。当事物不断减半或加倍时会出现对数,如示例中的k

答案 2 :(得分:1)

正如您所建议的那样,提供的示例将是O(log n),因为无论 n 的大小如何, k 都会乘以常量。通过比较两个非常简单的测试用例的必要遍历,也可以观察到这种行为。

例如,如果n = 10,则很容易证明程序将循环遍历循环6次。
然而,如果你将 n 的值加倍到n = 20,程序将只需要一次遍历,而你会期望一个O(n)的程序需要大约两倍的程序遍历作为原始测试用例。

答案 3 :(得分:1)

Example: 1~9

       1
     /   \
    2     3
   / \   / \ 
  4   5 6   7
 /           \
8             9

树的深度(或关注1 2 4 8 ...)也是⌊O(logn)⌋+ 1,因此复杂度为O(log n)