On Feb 10, 9:36*am, Morris Dovey <mrdo...@iedu.com> wrote:
> Willem wrote:
> > You may notice that it uses tail recursion.
> > A good compiler would rewrite the above code to:
>
> > *node *rev(node *head, *reversed_tail)
> > *{
> > * tail_recurse:
> > * *if (head) {
> > * * *node *next = head->next;
> > * * *head->next = reversed_tail;
> > * * */* return rev(next, head); */
> > * * *reversed_tail = head; head = next; goto tail_recurse;
> > * *}
> > * *return reversed_tail;
> > *}
>
> Which (with cut-n-paste + minor tweak) "cleans up" to
>
> * *node *rev(node *head, *reversed_tail)
> * *{ *while (head)
> * * * { *node *next = head->next;
> * * * * *head->next = reversed_tail;
> * * * * *reversed_tail = head;
> * * * * *head = next;
> * * * *}
> * * * *return reversed_tail;
> * *}
>
> Which eliminates the goto, the call/stack overhead, Kaz's
> re-entrancy issue - but doesn't address the Dan's interest in a
> recursive function.
>
> No matter - /I/ like it.
You really aren't done tweaking yet. You can make reversed_tail a
local variable initialized to NULL, since that's all the caller does
with it.
Now you should _really_ like the fact that what this code does is, as
pseudocode,
set Y empty
while (list X is not empty)
push(pop(X), Y)
return Y
...which is the traditional iterative list reverser you will find in
some textbooks.
This is one of many cases where starting with a "recursive" functional
definition and transforming it with algebraic operations that preserve
behavior yields an efficient C code.