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

时间:2012-04-06 04:24:45

标签: algorithm big-o

此功能为O(log(n))。为什么?它不是循环到n?

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

顺便说一句,我对O(n)分析很新。这个函数确实看起来是O(n),因为它循环到n。

4 个答案:

答案 0 :(得分:7)

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

答案 1 :(得分: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)。这里要考虑的重要一点是几何系列算术系列之间的区别,它为您提供了不同的运行时。

答案 2 :(得分:5)

这个循环是O(n):

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

因为$i采用了值:

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

但是这个循环只有O(log(n)):

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

因为$i采用了值:

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

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

答案 3 :(得分:5)

你的代码循环到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),类似于二进制树搜索在每次迭代时将搜索空间减半的方式。