为什么counter = counter / 2;有O(log(n))?

时间:2011-03-21 17:07:17

标签: c algorithm complexity-theory big-o

我知道以下代码的复杂度为O(log(n)):

while (n>1)
{
    counter++;
    n/=2;
}

据我所知,n在每次迭代时被分成两半,这意味着如果n为1000,则需要十轮才能离开循环。这是如何导致O(log(n))的?

对不起这个简单的问题,在我问之前,我真的尽力去做。

5 个答案:

答案 0 :(得分:6)

每次循环时,除以2(粗略;这将忽略舍入,因为它是渐近参数)。因此,如果在开始时n = N,则在k次迭代之后,n = N /(2 ^ k)。要达到n = 1,你必须满足2 ^ k = N.即,k = log(N)。

答案 1 :(得分:2)

重现关系将是

 T(n) = T(n/2) + O(1)

尝试使用Master's theorem解决它将使T(n)的运行时间为O(log n)(类似于二进制搜索中的内容)。

答案 2 :(得分:0)

假设n是2 ^ x(例如2 ^ 5 = 32,2 ^ 10 = 1024等),因此计数器在循环内递增x次。根据定义,x是基数2 log n。

答案 3 :(得分:0)

根据定义,对数不是线性的。换句话说,它们根据输入而改变不同的量。在您的示例中,第一步将n减少500,而第五步减少仅减少32.您越接近一,慢n减少。这种“减速”正是您通过日志获得的行为。

答案 4 :(得分:0)

一个简单的手动解释:如果你加倍n会发生什么?运行时是否加倍(即O(n))?不,运行时增加只有一步。这是典型的O(log n)。

[OTOH,如果你平方n(比如它从4增加到16),那么你会发现步数加倍。再次,指示O(log n)。]