作为初学程序员,我总是很难注意到有时简单代码的复杂性。有问题的代码是:
k = 1;
while (k <= n){
cout << k << endl;
k = k * 2;
}
起初,由于k = k * 2线,我认为复杂度为O(log n),我将代码作为测试运行并跟踪它在n的大小上循环的次数,即使是大尺寸的n也相对较低。我也很确定它不是O(n),因为它可能需要更长的时间来运行,但我可能在那里错了,因为这就是我提出这个问题的原因。
谢谢!
答案 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)