I am not able to understand the recursion of functions. How it works? how the values are stored and all?

后端 未结 4 1008
名媛妹妹
名媛妹妹 2021-01-28 04:19

I am not able to understand the recursion of functions. How it works? how the values are stored and all?

int tree_size(struct node* node) { 
  if (node==NULL) {         


        
相关标签:
4条回答
  • 2021-01-28 04:41

    The analogy with using pieces of paper (by @nhahtdh in the comments to Q) is very good. Let me elaborate on it.

    First, re-write your code in more linear manner:

    int tree_size(struct node* node) { 
      if (node==NULL) {
        return(0); 
      } else { 
        x = tree_size(node->left);
        y = tree_size(node->right);
        z = x + y;
        r = z + 1;
        return( r ); 
      } 
    }
    

    Imagine you have a thick (practically inexhaustible) stack of empty sheets of paper in front of you. You also have various recipes (function definitions) to the left of you on your desk, and an empty space to the right of you.

    Now, to call a function means to copy its definition from its recipe onto the sheet of paper on top of the stack of papers in front of you, then substitute the argument values of the call for the function parameters, and go on from there.

    When you hit a line with a function call on it (any function call), mark that line on the sheet of paper in front of you, move that paper to your right (faced up), and start working on the new empty sheet of paper in front of you. Copy onto it the recipe for the function that you need to call, write down the argument values, and continue working on it according to the recipe now in front of you.

    If you encounter another function call, repeat this sequence of actions: mark the line that needs to receive the result of the function call, put your current sheet of paper on top the pile to your right (facing up), copy the new recipe on the top sheet of paper in front of you, and go on from there as before.

    Now when you hit a line in the current recipe that says return, write down the returned value onto the top sheet of paper in the pile to your right on the marked line there, then discard the current piece of paper in front of you and move back the top piece of paper from the stack of papers to you right onto the stack of papers in front of you.

    That's it. All you needed were the two stacks of sheets of paper, one in front of you, and another one to your right, and the pile of papers with functions' definitions written on them, to your left.

    Notice, we don't care if the function that we call is the same as one of the previous function calls that we performed, or not. It works just the same.

    0 讨论(0)
  • 2021-01-28 04:44

    consider the follow three

         1
      2     3
     4 5   6
    7
    

    1 has two children (2 and 3) 2 has two children (4 and 5) .. 4 has one child (7)
    and you want to know the size of the tree at 1:

    tree_size(tree1);
    

    because tree1 is not NULL the if-condition not true, so the else statement will be executed:

    tree_size(tree1): return tree_size( tree_size(tree2) + tree_size(tree3) + 1 )
    

    same for tree2 and tree3

    tree_size(tree2): return tree_size( tree_size(tree4) + tree_size(tree5) + 1 )
    tree_size(tree3): return tree_size( tree_size(tree6) + tree_size(NULL) + 1 )
    

    and so on. Now if we substituate the return value of tree_size(tree2) and tree_size(tree3) in tree_size(tree1) we would get:

    tree_size(tree1): return tree_size( tree_size(tree4) + tree_size(tree5) + 1 + tree_size(tree6) + tree_size(NULL) + 1 + 1 )
    

    Now you can see the term 1+1+1, this is the size of the tree for the first two niveau's, if we keep substituating the tree_size calls, w'll get an some of n times 1, with n the size of the tree

    0 讨论(0)
  • 2021-01-28 04:59

    I think the line that is confusing you most is..

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

    If you called this function on the top node, it will tell you that the number of nodes in the tree is the number of nodes to the left, plus the number to the right, plus this on node you just called the function on.

    Now, I don't think it's the recursion that is confusing you, if it is, leave a comment and I can explain that a bit more.

    The problem I think you are having is what order the line will be executed. Well, it follows the logical maths rules for 'addition'. Note, we know we do not have to get concerned with operator overloads, as tree_size is returning an int, so we have

    intA + intB + intC;
    

    I trust I do not need to tell you that it does not matter what order you add these three values, you will get the same result.

    however, the order that these are added is well defined. If you think of the + operator as it's function, it will be a bit clearer. We basically have (and I hope I get this right):

    operator+(intA , operator+( intB, intC);
    

    so, you can see, we need to first calculate B + C before we can add on A, or if we take this back to the line of code in question, we get the tree_size on the right first, add one to it, then add on the tree_size of the left. This is an important thing to be aware of, you could do something very strange, such as edit the tree size when you get the value... say, if you moved nodes from one side to the other. Of course, it would be a very bad tree if getting the size of it was not something you can rely on.

    I fear I might have gone on a bit too much here, so if I have missed the mark a bit, just leave a comment and I will gladly try to help improve this answer for you.

    0 讨论(0)
  • 2021-01-28 05:01

    When entering a function, a new stack frame is created (on the stack in memory). The stack frame keeps track of the local data within that function, such as locally defined variables and incoming arguments. (And other things such as return address and previously stored register values that must be preserved. However this is not as relevant for this question.)

    With recursion, when you call a function from within the same function , you create a new stack frame (as with any call), and that new stack frame will store the local variables for the new call.

    As C. Stoll pointed out, the order of the two calls is unspecified, due to the + operator.

    0 讨论(0)
提交回复
热议问题