用递归计算大O表示法

时间:2017-11-21 03:48:19

标签: python python-3.x big-o notation

我试图理解Big O Notation最坏情况运行时。 但我仍然不太明白。

这是我最近写的一些代码:

def g(n):
    if n==0:
        return 1
    elif n==1:
        return 2
    else:
        n_div=n//2
        n_mod=n%2
        return g(n_div)*g(n_mod)

所以我希望我至少是对的:

def g(n):
    if n==0:
        return 1

elif n==1:
    return 2

是O(1),所以不变。

但是else部分呢。

是O(n)因为它取决于我选择的n吗?

任何人都可以解释else部分的Big O复杂性是什么吗?

2 个答案:

答案 0 :(得分:2)

嗯,您已经注意到您可以将您的功能分成3个个案,并且已经确定前2个是O(1)。第三个稍微有些棘手,但你也可以把它分成两部分。

递归显然来自:

g(n//2)*g(n%2)

我们可以立即看到n%2将评估为0或1,这将再次解决前2个案例中的一个,因此我们可以忽略它。离开我们g(n//2)。通过将其重写为打印循环并检查输出,您会发现一些事情:

>>> n = 37
>>> while n > 1:
...     n //= 2
...     print(n)
...
18
9
4
2
1

正如您所看到的,每次术语减少一半,并且在递归中也会出现相同的情况。这是对数

因此,此函数的最坏情况是O(logn)。

通过查看this question,您可以详细了解logn在Big-O表示法中的实际含义。

答案 1 :(得分:0)

O符号实际上不是该程序的一部分。它确实衡量了运行时间随着输入大小的增加而增加的方式。在这种情况下,耗时的部分是最后的其他部分。

您需要了解这对您的计划有何用处。这是一个简单的实证分析,可以帮助您。如果我们对程序进行一点检测以打印出最终else部分为给定输入运行的次数,我们就会得到这个。

   n | times
-----+-----
   2 | 1
   4 | 2
   8 | 3
  16 | 4
  32 | 5
  64 | 6
 128 | 7
 256 | 8
 512 | 9
1024 | 10
2048 | 11
4096 | 12
8192 | 13

如果你这样做,你会看到类似的东西。

enter image description here

您可以看到,随着输入大小的增加,调用次数也会增加但是线性地增加。事实上,它是对数的,因为你的n每次迭代循环减少了50%。