特定递归函数的增长顺序

时间:2012-03-01 00:40:15

标签: c# math recursion big-o

以下功能的增长顺序是什么?

    static int counter = 0;

    static void Example(int n)
    {
        if (n == 1) return;

        for (int i = 0; i < n; i++)
        {
            counter++;
        }

        Example(n / 2);
    }

为了解决这个问题,我做了以下几点:

我首先摆脱内部for循环以便最终得到:

    static void Example(int n)
    {
        if (n == 1) return;            

        counter++;

        Example(n / 2);
    }

通过分析我能够判断出该方法的增长顺序是n的对数基数2。

所以我认为最终答案将是log base 2次。我怎么能搞清楚?

2 个答案:

答案 0 :(得分:6)

让我们看一下原始函数和修改过的函数。在原始函数中,您完成了以下工作量:

  • 基本案例检查的一定量工作。
  • O(n)努力计算数字。
  • 递归调用一半大小所需的工作。

我们可以将此表示为递归关系:

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

让我们看看这是什么样的。我们可以通过注意

开始扩展它
  

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

     

= n +(n / 2 + T(n / 4)

     

= n + n / 2 + T(n / 4)

     

= n + n / 2 +(n / 4 + T(n / 8))

     

= n + n / 2 + n / 4 + T(n / 8)

我们可以在这里看到一种模式。如果我们将T(n / 2)位扩展k次,我们得到

  

T(n)= n + n / 2 + n / 4 + ... + n / 2 k + T(n / 2 k

最终,当n / 2 k = 1时停止。当发生这种情况时,我们有

  

T(n)= n + n / 2 + n / 4 + n / 8 + ... + 1

这对此有何评价?有趣的是,该和等于2n + 1,因为和n + n / 2 + n / 4 + n / 8 + ... = 2n。因此,该第一函数是O(n)。我们也可以使用 Master Theorem 来得出这个结论,但看到这种方法也很有意思。


现在让我们来看看新功能。这一个

  • 基本案例检查的一定量工作。
  • 递归调用一半大小所需的工作。

我们可以将此重复写为

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

使用与以前相同的技巧,让我们展开T(n):

  

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

     

= 1 + 1 + T(n / 4)

     

= 1 + 1 + 1 + T(n / 8)

更一般地说,在扩展k次之后,我们得到了

  

T(n)= k + T(n / 2 k

当n / 2 k = 1时停止,这发生在k = log 2 n(即lg n)时。在这种情况下,我们得到了

  

T(n)= lg n + T(1)= lg n + 1

在这种情况下,所以T(n)= O(lg n)。

希望这有帮助!

答案 1 :(得分:0)

现在让我们看看......这会给计数器增加1次n次。 每个呼叫n减少一半,直到达到一个。

你可以摆脱循环并使用

counter+=n;

相反,因为基本上循环将n加1到计数器,逐个。

这意味着n每次运行时都会被添加到计数器中,然后变小2,直到达到1。

所以说n = 40。 计数器: 40 - &gt; 60 - &gt; 70 - &gt; 75 - &gt; 77 - &gt; 77。 N: 40 - &gt; 20 - &gt; 10 - &gt; 5 - &gt; 2 - &gt; 1。

只是推动正确的方向(计数器+ = n;是重要部分)