int print4Subtree(struct Node *root) {
if (root == NULL)
return 0;
int l = print4Subtree(root->left);
int r = print4Subtree(root->right);
if ((l + r + 1) == 4)
printf("%d ", root->data);
return (l + r + 1); }
该算法/代码在二叉树中找到具有恰好4个节点的子树数,它以自下而上的方式工作。 我知道这段代码的时间复杂度为O(n),空间复杂度为O(log n),因为它使用递归。
代码的重现关系是什么?
我尝试绘制T(n)= 2T(n-1)+1,这显然是错误的!
答案 0 :(得分:1)
在您更了解树结构的情况下,您只能单独讨论 n 中的递归关系,例如:
案例1:每个节点只有一个孩子的意思
T ( n )= T (0)+ T ( n -1 )+ k 。
案例2:任何级别的子树都是平衡的
T ( n )= 2 T (( n -1)/ 2)+ k < / em>的。
这两个都会导致O( n ),但这两种情况只是非常少数可能的树。对于更通用的方法,您必须使用类似 T ( n )= T ( a )+的公式 T ( b ),其中 a 和 b 是由于结构导致的子问题的任意划分你的树。您仍然可以使用strong induction从这种公式中建立结果。
以下是我将使用的确切公式和方法:
T ( n )= nk + m n c ,其中 m n ≤ n + 1.(注意:我使用 k 进行递归步骤的开销, c < / em>用于基本/空步骤的开销。)
基本情况( n = 0):
对于空节点 T (0)= c 所以 T ( n )= kn + m n c ,
其中 m n =1≤ n +1 = 1。
归纳步骤( T ( x )= xk + m x c 对于所有 x &lt; n ):
大小 n 的sub_tree有两个大小为 a 和 b 的子树( a 或 b 可能为0), n = a + b + 1。
T ( n )= T ( a )+ T ( b )+ k = ak + m a c + bk + m b c + k =( a + b +1) k +( m a + m b ) c = nk + m n c ,
其中 m n = m a + m b ≤ a + 1 + b + 1 = n + 1。
使用 m n 的原因仅仅是使证明更加平滑的形式,因为确实的空案例数是实际受树结构影响的(在前一种情况2中,它是log n )。所以 T ( n )充其量只是O( n ),因为 nk 一词,并且可以是no因为 m n c 上的绑定而比O( n )更差。