So, in fact, you can always reorganize a function into tail recursion ... Most people programming in other languages ββwill use a sequel to code it effectively. But we look in more detail here in C / C ++, so I assume that I get rid of this simply by coding the function itself (I mean without adding a general basis for the continuation to the language).
Suppose you have an iterative version of your function, which should look like this:
void iterative() { while (cond) dosomething() }
Then, turning it into a tail recursive function, is simply done by writing:
void tailrecursive() { if (!cond) return; dosomething(); tailrecursive(); }
In most cases, you need to pass the βstateβ to a recursive call, which adds additional parameters that were not previously useful. In your specific case, you have a pre-order tree traversal:
void recursive_preorder(node n) { if (n == visited) return; dosomething(n); foreach child_node in n.getChildren() { recursive_preorder(child_node); } }
The iterative equivalent should introduce a stack to memorize explorer nodes (so we add push / pop operations):
void iterative_preorder(node n) { if (n == visited) return; stack worklist = stack().push(n); while (!worklist.isEmpty()) { node n = worklist.pop() dosomething (n); foreach child_node in n.getChildren() { worklist.push(child_node); } } }
Now, taking this iterative version of the pre-order tree traversal and turning it into a tail recursive function, you need to give:
void tail_recursive_preorder_rec(stack worklist) { if (!worklist.isEmpty()) { node n = worklist.pop() dosomething (n); foreach child_node in n.getChildren() { worklist.push(child_node); } } tail_recursive_preorder_rec(worklist) } void tail_recursive_preorder (node n) { stack worklist = stack().push(n); tail_recursive_preorder_rec(worklist); }
And it gives you a recursive tail function that will be perfectly optimized by the compiler. Enjoy it!