Results 1 to 7 of 7

Thread: Dear Lord, please deliver me from RECURSION

  1. #1
    Join Date
    Jul 2012
    Posts
    201
    Thanks
    26
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Windows

    Default Dear Lord, please deliver me from RECURSION

    Hi guys, as always, trying to figure out a recursive function just hurts my brain. The function below works perfectly but I am a bit confused by line 13 and 14. If a recursive function calls itself inside a loop, what happens to the value of "i", does it ever get incremented. Lets take the code below as an example, lets assume the "length" of the vector "children" is 5, on the first iteration, the function calls itself and then what happens to the other 4 subsequent iterations of the loop. I hope my question is clear.

    Qt Code:
    1. void Html_Parser::tableData(GumboNode *node)
    2. {
    3. if (node->type != GUMBO_NODE_ELEMENT) {
    4. return;
    5. }
    6. GumboAttribute* href;
    7. if (node->v.element.tag == GUMBO_TAG_A &&
    8. (href = gumbo_get_attribute(&node->v.element.attributes, "href"))) {
    9. std::cout << href->value << std::endl;
    10. }
    11.  
    12. GumboVector* children = &node->v.element.children;
    13. for (unsigned int i = 0; i < children->length; ++i) {
    14. tableData(static_cast<GumboNode*>(children->data[i]));
    15. }
    16. }
    To copy to clipboard, switch view to plain text mode 

  2. #2
    Join Date
    Mar 2017
    Location
    New Hampshire, USA
    Posts
    4
    Qt products
    Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: Dear Lord, please deliver me from RECURSION

    "i" is local to the function and is stored on the call stack. When the function calls itself, a new value of "i" is created for that call. The function will call itself for each child node (which will in turn call itself for each child) until is processes a node with no children.

    This is a depth-first traversal of the nodes in the HTML document.

  3. #3
    Join Date
    Jul 2012
    Posts
    201
    Thanks
    26
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Dear Lord, please deliver me from RECURSION

    If I understand you correctly, the value of "i" will be 1 on the second call to the function even though you are calling the same function that will initialize "i" to zero every time you call it (i.e. line 13).
    Last edited by ayanda83; 29th March 2017 at 16:46.

  4. #4
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Dear Lord, please deliver me from RECURSION

    "i" is a local variable to the for() loop. It actually isn't used at all in the recursion - the argument to the recursive call is the "GumboNode" pointer to the "i-th" child of the node passed in the previous level of recursion.

    I think it would help you better understand if you drew a diagram that shows how the recursion progresses:

    Qt Code:
    1. Root node
    2. Child node 0
    3. Grandchild node 0 (Child 0 of root node's child 0)
    4. Great-grandchild node 0 (Child 0 of grandchild 0)
    5. Great-grandchild node 1
    6. Great-grandchild node 2
    7. ...
    8. Grandchild node 1
    9. Great-grandchild node 0 (Child 0 of grandchild 1)
    10. Great-grandchild node 1
    11. Great-grandchild node 2
    12. ...
    13. Child node 1 (of root node)
    14. Grandchild node 0 (Child 0 of root node's child 1)
    15. Great-grandchild node 0 (Child 0 of grandchild 0)
    16. Great-grandchild node 1
    17. Great-grandchild node 2
    18. ...
    19. Grandchild node 1
    20. Great-grandchild node 0 (Child 0 of grandchild 1)
    21. Great-grandchild node 1
    22. Great-grandchild node 2
    23. ...
    24. and so forth.
    To copy to clipboard, switch view to plain text mode 

    The integers (0, 1, 2...) are the value of "i" used to retrieve the child node that starts the next level of recursion. This is called 'depth-first" recursion because each branch of the tree starting at the root node is traversed completely to the end (by indexing the 0-th child). It then backs up on level, gets the 1-th child, then explores the tree that starts with its 0th child, until the tree starting at the root has been explored.

    The recursive function you show has three criteria for stopping: first, the node passed in isn't the right type; second, the node doesn't have any children; or third, all of the children have been examined. In any case, if the recursion was called from within the for() loop, when the recursive call returns, the local value of "i" will be whatever it was when the function was called. So if the loop variable "i" was 1 when the function was called, it will be 1 again when the recursion returns back to the level where it started. It gets incremented when the loop goes around again, and a new descent into the tree starts.

    The alternative is "breadth-first" recursion, which I'll let you use Google to learn about.
    Last edited by d_stranz; 29th March 2017 at 17:39.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  5. #5
    Join Date
    Jul 2012
    Posts
    201
    Thanks
    26
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Dear Lord, please deliver me from RECURSION

    Thank you very much d_stranz for taking the time answer my question. I think I understand now. All recursion does is to suspend computation of the function every time it encounters a call to itself. So if the function calls itself 5 times then there should be 4 suspended computations on the stack before it encounters a base-case which will cause function to return and of course working backwards on the suspended computation on the stack.

  6. #6
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,714
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: Dear Lord, please deliver me from RECURSION

    Generally it is advisable to substitute recursion with iteration.
    There are several advantages but the main two are:
    1. you can't get in to an infinite loop
    2. the code is easier to read which makes it less prone to error and easier to maintain.
    Here is the first google result I got, there are plenty more:
    http://stackoverflow.com/questions/1...n-to-iteration

    Also, when you refactor a recursive function to iteration you learn what it does much easier.
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  7. The following user says thank you to high_flyer for this useful post:

    d_stranz (31st March 2017)

  8. #7
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Dear Lord, please deliver me from RECURSION

    Also, when you refactor a recursive function to iteration you learn what it does much easier.
    Generally because it takes quite a while to find all the bugs you introduce in the process

    If you don't have to worry about stack overflow (i.e. the recursion doesn't go very deep) then sometimes recursion is the simplest way to go from the mathematical expression to a program. The classic example is computing factorials: f(n) = n * f(n-1) where the ending condition is f(1) = 1. Or visiting all the nodes in a tree as in the current example.

    You could spend quite a while trying to turn a simple recursive algorithm into an iterative one. If recursion works to solve your problem, then write it that way and get on with the next piece of code. Just be sure you understand when it could fail - for example, the factorial algorithm can quickly run into integer overflow.

    The goal is to write correct programs, on schedule. Go with what is fastest to write and won't come back to bite you in the form of a bug.

    Good link to an interesting stackoverflow discussion. Thanks.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

Similar Threads

  1. Replies: 1
    Last Post: 11th October 2011, 08:28
  2. Recursion Problem
    By kingfinn in forum Qt Programming
    Replies: 0
    Last Post: 23rd January 2010, 21:15
  3. endless recursion with QDir
    By roxton in forum Qt Programming
    Replies: 2
    Last Post: 16th January 2009, 23:04
  4. Singleton pattern - end in recursion
    By probine in forum General Programming
    Replies: 6
    Last Post: 29th March 2006, 13:08

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.