【问题标题】:Recursion in return statement [closed]返回语句中的递归[关闭]
【发布时间】:2015-01-25 10:32:44
【问题描述】:

谁能解释一下return语句中两个递归函数的执行,像这样

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


struct node* newNode(int data)
{
    struct node* node = (struct node*)malloc(sizeof(struct node));
    node->data = data;
    node->left = NULL;
    node->right = NULL;
    return(node);
}

int size(struct node* node) 
{
    if (node==NULL) 
        return 0;
    else    


  return(size(node->left) + 1 + size(node->right));


}


int main()
{

    struct node *root = newNode(1);
    root->left        = newNode(2);
    root->right       = newNode(3);
    root->left->left  = newNode(4);
    root->left->right = newNode(5);   
    printf("Size of the tree is %d", size(root));  
    getchar();
    return 0;
}

在这种情况下,size() 函数如何在 return 语句中执行,无论是从左到右还是从右到左!我想知道这两个函数的执行流程。

【问题讨论】:

  • 如果你使用int s=size(node->left) + 1 + size(node->right); return s;会不会更方便?
  • 肯定会,但我更想知道 return 语句中的两个递归函数是如何执行的。它们是并行执行还是以某种从左到右或从右到左的方式执行!
  • 它不会并行执行,因为 C 不是并行语言。查看Order of evaluation,你会发现并不能保证首先执行哪个递归函数。
  • 函数不会并行执行。它们可以从右到左、从左到右、从中间往前或以任何其他顺序执行,但不能并行执行。

标签: c function recursion data-structures tree


【解决方案1】:

递归由两个概念驱动,传播条件和终止条件。

条件 (node == NULL) 是递归的终止条件,size(node->left) + 1 + size(node->right) 是传播条件,从root 和后续节点,并将节点本身的大小加 1。

为了充分解释你,我们需要一个样本树

3 4 5 1 2 9 8

样本树的递归是这样的

size(3)
 = size(4) + size(5)       + 1

现在让我们看看size(4) = size(1) + size (2) + 1 size(1) = size(NULL) + 1 = 0 + 1 = 1(因为 1 没有左边,如果节点为 NULL,则函数返回 0 - 终止条件) 大小(2) = 大小(NULL) + 1 = 0 + 1 = 1 因此 size(4) 是 3

以类似的方式,size(5) 也将是 3,因此 size(1) = 3+3+1 = 树中的 7 个节点

因此执行是

size (3) 
size (4) + size (5) + 1
size (1) + size (2) + 1 + size(9) +size (8) + 1
size (NULL) + 1 +size (NULL) + 1  + 1 +size (NULL) + 1  +size (NULL) + 1  +1

最终的回报是

return 0 + 1+ 0+1+1+0+1+0+1+1 

返回 7

【讨论】:

    【解决方案2】:

    这是顺序

    size(root)
    =size(root->left) + 1 + size(root->right)
    =(size(root->left->left) + 1+ size(root->left->right)) + 1 + size(root->right)
    =((size(root->left->left->left) + 1 + size(root->left->left->right)) + 1+ size(root->left->right)) + 1 + size(root->right)
    =((0 + 1 + size(root->left->left->right)) + 1+ size(root->left->right)) + 1 + size(root->right)
    =((0 + 1 + 0) + 1+ size(root->left->right)) + 1 + size(root->right)
    =(1 + 1+ size(root->left->right)) + 1 + size(root->right)
    =(1 + 1+ (size(root->left->right->left) +1+ size(root->left->right->right)) + 1 + size(root->right)
    =(1 + 1+ (0 +1+ size(root->left->right->right)) + 1 + size(root->right)
    =(1 + 1+ (0 +1+ 0)) + 1 + size(root->right)
    =(1 + 1+ 1) + 1 + size(root->right)
    =(3) + 1 + (size(root->right->left)+ 1 +size(root->right->right))
    =(3) + 1 + (size(root->right->left->left)+ 1+ size(root->right->left->right))+ 1 +size(root->right->right))
    =(3) + 1 + (0+ 1+ size(root->right->left->right))+ 1 +size(root->right->right))
    =(3) + 1 + (0+ 1+ 0)+ 1 +size(root->right->right))
    =(3) + 1 + (1)+ 1 +(size(root->right->right->left)+1+ size(root->right->right->right))
    =(3) + 1 + (1)+ 1 +(0+1+ size(root->right->right->right))
    =(3) + 1 + (1)+ 1 +(0+1+ 0)
    =(3) + 1 + (1)+ 1 +(1)
    =(3) + 1 + (3)
    =7
    

    代码顺序如下:

    //step 1
    size(root)
    {
        //node===root
        if (root==NULL)//no
            return 0;
        else
            return(size(root->left) + 1 + size(root->right));
            //it will call size(root->left)
           //after size(root->left) it will plus 1 then will call size(root->right)
    }
    //step 2
    size(root->left)
    {
    
        if (root->left==NULL)//no
            return 0;
        else
            return(size(root->left->left) + 1 + size(root->left->right));
    }
    //step 3
    size(root->left->left)
    {
    
        if (root->left->left==NULL)//no
            return 0;
        else
            return(size(root->left->left->left) + 1 + size(root->left->left->right));
    }
    //step 4
    size(root->left->left-->left)
    {
    
        if (root->left->left==NULL)//yes
            return 0;
        //it returns to step 3
    
    }
    //step 5 from step 3
    size(root->left->left)
    {
    
        if (root->left->left==NULL)//no
            return 0;
        else
            return(0 + 1 + size(root->left->left->right));
           //size(root->left->left->left==0
           //now it calls size(root->left->left->right)
    }
    //step 6 from step 5
    
    size(root->left->left->right)
    {
    
        if (root->left->left->right)//yes
            return 0;
        //it retuns to step 5
    }
    //step 7 from step 3
    size(root->left->left)
    {
    
        if (root->left->left==NULL)//no
            return 0;
        else
            return(0 + 1 + 0);//==1
           //size(root->left->left->right)==0
           //now it returns to 2
    }
    

    希望您能理解其余部分。

    【讨论】:

      猜你喜欢
      • 2015-12-22
      • 2010-10-30
      • 2014-02-03
      • 2013-08-25
      • 1970-01-01
      • 2019-10-07
      • 1970-01-01
      • 2016-02-13
      • 2017-07-21
      相关资源
      最近更新 更多