理解递归函数

时间:2011-05-06 04:58:11

标签: c recursion binary-tree

基于下面的二叉树,函数调用mystery(root)的输出是什么?

 struct treenode {
      int data;
      struct treenode* left;
      struct treenode* right;
 }

 void mystery(struct treenode* root) {
     if (root == NULL) return;

     mystery(root->right);
     mystery(root->left);

     if (root->data%2 == 0) {
         root->data /= 2;
     }
     else {
         int sum = 0;
         if (root->left != NULL) sum += root->left->data;
         if (root->right != NULL) sum += root->right->data;
         root->data += sum;
     }
     printf(“%d “, root->data);
}

二叉树: 63 | 47 16 | 86 32 NULL 9 | NULL NULL 95 NULL NULL NULL 53 64 |

这是我对功能的理解:

mystery(63->right)
mystery(63->left)

然后它将检查root-> data(63)是否为奇数或其他 因为它很奇怪,那么

sum += root->left(47)
sum += root->right(16)
root->data(63) += sum, 

所以现在sum =?

然后它将递归地称为神秘(46)和神秘(16)

这是正确的想法吗?

2 个答案:

答案 0 :(得分:4)

请注意,对给定节点的子节点的递归调用发生在之前计算该节点的值。 (这可能对您来说很清楚,但我不能从您说出问题的方式来判断。)因此,当计算根节点的总和(值63)时,其两个孩子的值已经是改性。 (见下文)

如果节点具有奇数值,则其新值将是其自身值与其子节点的新值之和,由递归调用分配。奇怪的是,如果给定节点的值甚至是开始的,则其新值与其子节点的值无关。它只是原始值的一半。

由于您的问题似乎是关于理解递归的流程,所以这些图表可能会有所帮助。这是原始树:

             [63]
            /   \
         [47]   [16]
         /  \       \
      [86]  [32]    [9]
         \         /  \
        [95]    [53]  [64]

调用mystery函数后,以下是新值:

              106+8+63=[177]
                  /         \
    43+16+47=[106]          16/2=[8]
           /      \                 \
    86/2=[43]   32/2=[16]        53+32+9=[94]
           \                            /    \
      95+0=[95]                53+0=[53]  64/2=[32]

要了解事情发生的顺序,请记住,每个节点的值都会计算并在对其子项进行递归调用后打印。这被称为“邮政订单遍历”,虽然通常你从左到右递归地访问孩子,而在这里我们从右到左访问他们。下图显示了访问节点的顺序。

                 9[177]
               /       \
           8[106]      4[8]
         /      \          \
      7[43]     5[16]      3[94]
         \                 /   \
        6[95]          2[53]   1[32]

打印节点值会产生以下输出:

32 53 94 8 16 95 43 106 177

可能有点矫枉过正,但我​​希望有所帮助。

答案 1 :(得分:0)

对于此树的每个节点,此代码执行以下操作。

  1. 如果节点的数据是偶数值,则将其除以2并打印结果值。
  2. 如果节点的数据是奇数值,则会在其中添加其两个子节点的数据并打印结果值。
  3. 例如,包含数据的节点为86,它是打印43.对于包含数据为47的节点,它打印47 + 86 + 32 = 165。