I've used recursion quite a lot on my many years of programming to solve simple problems, but I'm fully aware that sometimes you need iteration due to memory/speed problems.
So, sometime in the very far past I went to try and find if there existed any "pattern" or text-book way of transforming a common recursion approach to iteration and found nothing. Or at least nothing that I can remember it would help.
- Are there general rules?
- Is there a "pattern"?
One pattern to look for is a recursion call at the end of the function (so called tail-recursion). This can easily be replaced with a while. For example, the function foo:
ends with a call to foo. This can be replaced with:
which eliminates the second recursive call.
Generally the technique to avoid stack overflow is for recursive functions is called trampoline technique which is widely adopted by Java devs.
However, for C# there is a little helper method here that turns your recursive function to iterative without requiring to change logic or make the code in-comprehensible. C# is such a nice language that amazing stuff is possible with it.
It works by wrapping parts of the method by a helper method. For example the following recursive function:
Turns into:
Another simple and complete example of turning the recursive function into iterative one using the stack.
A rough description of how a system takes any recursive function and executes it using a stack:
This intended to show the idea without details. Consider this function that would print out nodes of a graph:
For example graph: A->B A->C show(A) would print B, A, C
Function calls mean save the local state and the continuation point so you can come back, and then jump the the function you want to call.
For example, suppose show(A) begins to run. The function call on line 3. show(B) means - Add item to the stack meaning "you'll need to continue at line 2 with local variable state node=A" - Goto line 0 with node=B.
To execute code, the system runs through the instructions. When a function call is encountered, the system pushes information it needs to come back to where it was, runs the function code, and when the function completes, pops the information about where it needs to go to continue.
Thinking of things that actually need a stack:
If we consider the pattern of recursion as:
For example, the classic Tower of Hanoi
This can be translated into a loop working on an explicit stack, by restating it as:
For Tower of Hanoi this becomes:
There is considerable flexibility here as to how you define your stack. You can make your stack a list of
Command
objects that do sophisticated things. Or you can go the opposite direction and make it a list of simpler types (e.g. a "task" might be 4 elements on a stack ofint
, rather than one element on a stack ofTask
).All this means is that the memory for the stack is in the heap rather than in the Java execution stack, but this can be useful in that you have more control over it.
This link provides some explanation and proposes the idea of keeping "location" to be able to get to the exact place between several recursive calls:
However, all these examples describe scenarios in which a recursive call is made a fixed amount of times. Things get trickier when you have something like: