递归树排序

时间:2012-10-07 10:29:27

标签: algorithm recursion

我已经尝试确定递归关系给出的运行时间,但我的结果不正确。

复发

T(n) = c + T(n-1) if n >= 1
     = d          if n = 0

我的尝试

我构造了这个递归树:

                   n
                   |
                  n-1
                   |
                  n-2
                   |
                  n-3
                   |
                  n-4
                   |
                  n-5
                   |
                   |
                   |
                   |
                   |
                   |
                Till we get 1

现在处于i级别,子问题的大小应为n-i

但最后我们想要一个大小为1的问题。因此,在最后一级,n-i=1给出了i=n-1

因此,树的深度变为n-1,高度变为n-1+1= n

现在解决这个递归所需的时间=树的高度*每个级别所需的时间是:

n+(n-1)+(n-2)+(n-3)+(n-4)+(n-5)+ ...
==> (n+n+n+n+n+ ... )-(1+2+3+4+5+ ... )
==> n - (n(n+1)/2)

现在所花费的时间= n *((n-n2)/ 2),它应该使顺序为n 2 ,但这不是正确的答案。

3 个答案:

答案 0 :(得分:3)

  

现在在第i级,子问题的大小应该是,n-i

是的,这是正确的。但是你假设,运行时等于所有子问题大小的总和。试想一下,已经总结前两个级别给出n + (n - 1) = 2n - 1,为什么问题规模会增加? 免责声明:有点手写,而不是完全准确的陈述。

公式实际上是什么

T(n) = c + T(n-1)

公式说,为某些n求解它需要花费相同的时间来解决问题大小少一点,加上一个额外的常量cc + T(n - 1)

将上述陈述放在上面的另一种方法是:如果问题需要花费一些时间t来解决某个问题的大小问题,那么问题大小需要t + c,大一点。< / p>

我们知道,问题大小为n = 0时,需要时间d。根据第二个声明,对于另一个n = 1的大小,它将需要d + c。再次应用我们的规则,d + c + c需要n = 2。我们的结论是,任何d + n*c都必须花费n时间。

不是证据。要真正证明这一点,你必须使用amit所示的归纳法。

正确的递归树

您的递归树仅列出问题大小。我很害怕,这几乎没用。相反,您需要列出所述问题大小的运行时。

中的每个节点都对应到某个问题大小。您在该节点中写入的内容是问题大小所需的附加时间。即您将节点的所有后代加上加上节点本身,以获得特定问题大小的运行时。

这种树的图形表示看起来像这样

Tree        Corresponding problem size
c                                    n
|
c                                    n - 1
|
c                                    n - 2
|
c                                    n - 3
.
.
.
|
c                                    2
|
c                                    1
|
d                                    0

正式化:如前所述,节点的标签是解决该问题大小及其所有后代所需的附加运行时。最上面的节点表示问题大小为n,带有标签c,因为它是T(n-1)的补充,它使用|连接到它。

在公式中,您只能编写此关系:T(n) = c + T(n-1)。鉴于该树,您可以看到这适用于每个n>=1。你可以这样写下来:

T(n)     = c + T(n - 1) # This means, `c` plus the previous level
T(n - 1) = c + T(n - 2) # i.e. add the runtime of this one to the one above^
T(n - 2) = c + T(n - 3)
...
T(n - (n - 2)) = c + T(1)
T(n - (n - 1)) = c + T(0)
T(0) = d

您现在可以从下到上扩展术语:

T(n - (n - 1)) = c + T(0)
T(0) = d

T(n - (n - 2)) = c + T(1)
T(n - (n - 1)) = c + d
T(0) = d

T(n - (n - 3)) = c + T(2)
T(n - (n - 2)) = c + (c + d)
T(n - (n - 1)) = c + d
T(0) = d

T(n - (n - 4)) = c + T(3)
T(n - (n - 3)) = c + (2*c + d)
T(n - (n - 2)) = c + (c + d)

...

T(n) = c + T(n - 1)
T(n - 1) = c + ((n-2)c + d)

T(n) = c + (n-1)c + d = n*c + d
T(n - 1) = (n-1)c + d

汇总1 to n

n+(n-1)+(n-2)+(n-3)+(n-4)+(n-5)+ ...
==> (n+n+n+n+n+ ... )-(1+2+3+4+5+ ... )
==> n - (n(n+1)/2)

从第一行到第二行,您已将问题从总结1 to n减少到总结1 to n-1。这不是很有帮助,因为你遇到了同样的问题。

我不确定你在第三行上做了什么,但你从第一行到第二行的转换基本上是正确的。

这将是正确的公式:

gauss' trick to sum 1 to n

答案 1 :(得分:2)

T(n) = c + T(n-1) 
     = c + (c + T(n-2)) 
     = ... 
     = c*i + T(n-i) 
     = ...
     = c*n + T(0)
     = c*n + d

如果我们假设c,d是常数 - 它会得到O(n)

要以数学方式证明 - 可以使用mathematical induction

每个k < n假设T(n) = c*n + d
基数为T(0) = 0*n + d = d,其对于n <1是正确的。 1

T(n) = c + T(n-1)               (*)
     = c + (n-1)*c + d 
     = c*n + d

(*)是归纳假设,并且是有效的,因为n-1&lt; Ñ

答案 2 :(得分:1)

复杂性为O(n)。

正如您所描述的那样,函数通过使用常量运算'c'将输入n的问题转换为(n-1)的问题。

因此,向下移动递归树,我们将总共有n个级别,并且在每个步骤中我们需要一些常量操作'c'。

因此将会有总c * n运算导致复杂度O(n)。