2012-04-06 95 views
4

这个函数是O(log(n))。为什么?它不是循环到n吗?为什么这个函数/循环O(log n)而不是O(n)?

function fxn($n) { 
    for ($i = 1; $i <= $n; $i *= 2) 
     echo $i; 
} 

我很新的O(n)分析的方式。这个函数确实看起来是O(n),尽管它循环到n。

+0

很多很好的答案,说几乎完全相同的东西;-) – 2012-04-06 04:34:04

+1

对不起,大家好,我认为1更有意义的初始化我我:) – 2012-04-06 04:34:58

回答

5

这个循环将是O(N):

function fxn($n) { 
    for ($i = 0; $i <= $n; $i++) 
     echo $i; 
} 

因为$i取值为:

1, 2, 3, 4, 5, 6, 7, ..., n 

但这种循环只有O(日志(N)):

function fxn($n) { 
    for ($i = 1; $i <= $n; $i *= 2) 
     echo $i; 
} 

因为$i取值:

1, 2, 4, 8, 16, 32, 64, ..., n 

以这种方式增长的序列称为“对数”。

+0

我认为你的第一个示例代码是'O(1)',因为它运行的次数不变。 – fanjavaid 2017-04-14 08:07:41

+1

@fanjavaid第一个函数迭代'n'次。随着'n'的增长,循环的迭代次数也会增加。如果n是10亿,则循环运行10亿次。这是标准的“O(n)”操作。 – theJollySin 2017-04-14 14:50:24

5

注:因为你是从0开始的功能永远不会结束,并且0 * 2 = 0。我会假设你的循环在1

循环递增多重启动每次有2,这就是为什么运行时是O(lg(n))

让我们考虑一个简单的例子,其中n = 128

这里是i的值,对于每一次迭代:1,2,4,8,16,32,64,128。因此,你已经走了通过8个值。

lg(128) = 7 (lg = log in base 2) 
     = 8 - 1 

请注意,- 1是一个常数,所以它不会影响我们的运行时计算。

如果循环增加1(或任何常数k),则运行时间为O(n)。这里要考虑的重要事项是几何系列算术系列之间的差异,它给您不同的运行时间。

+0

lg(32)= 5,但你有正确的想法。 – erickson 2012-04-06 04:34:32

+0

哎呀,纠正它:) – 2012-04-06 04:36:11

7

它没有循环遍历所有元素,在每一步中它跳过前一步骤的两倍 - 因为$i *= 2部分。也就是说,假设$i从大于零的值开始,否则就是无限循环:$i在写入时总是0

4

你的代码循环达到n,但是而不是通过使它成为O(n)的那个(或任何常数值)。

是它做什么:

 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 
     | |  |   |      | 
     +--+-----+-----------+-----------------------+ 
Steps 1 2  3    4 

因为它的每一次增加一倍,它实际上是为O(log N),类似的方式二叉树搜索减半每次迭代的搜索空间。

相关问题