Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rewriting a recursive function without using recursion

I'm rewriting some existing code in a setting where recursive calls are not easily implemented nor desired. (And in Fortran 77, if you must know.) I've thought about making a stack from scratch to keep track of the calls needed, but this seems kludgy, and I'd rather not allocate memory to an array in cases where the recursion is not deep. (I'm not confident that Fortran 77 supports dynamic array sizing either.)

Any other suggestions for a general solution on how to take an obviously recursive function and rewrite it non-recursively without wasting space on a stack?

Many thanks, Old McSt

like image 208
Old McStopher Avatar asked Dec 12 '10 14:12

Old McStopher


People also ask

What can I use instead of recursion?

Moreover, iterative solutions are usually more efficient than recursive solutions as they don't incur the overhead of the multiple method calls. We use Recursion when we have to perform a complex task that can be broken into the several subtasks. Recursion is implemented as a method that calls itself to solve subtasks.

Can a recursive function be made without using the return statement?

It is not strictly necessary with return statements at all just to achieve recursion either.

Can you avoid recursion?

To avoid recursive triggers you can create a class with a static Boolean variable with default value true. In the trigger, before executing your code keep a check that the variable is true or not. Once you check make the variable false.

Can you always replace recursive with iterative?

Recursion is nothing just calling the same function on the stack and once function dies out it is removed from the stack. So one can always use an explicit stack to manage this calling of the same operation using iteration. So, yes all-recursive code can be converted to iteration. Save this answer.


2 Answers

If your code uses tail recursion (that is, the function returns the result of every recursive call directly without any other processing) then it's possible to rewrite the function imperatively without a stack:

function dosomething(a,b,c,d) 
{
  // manipulate a,b,c,d
  if (condition) 
    return dosomething(a,b,c,d) 
  else
    return something;
}

Into:

function dosomething(a,b,c,d) 
{
  while (true) 
  {
    // manipulate a,b,c,d
    if (condition) continue;
    else return something;
  }
}

Without tail recursion, using a stack (or a similar intermediary storage) is the only solution.

like image 189
Victor Nicollet Avatar answered Sep 29 '22 19:09

Victor Nicollet


The classic recursive function that can be written as a loop is the Fibonacci function:

 function fib(n)
 {
     // valid for n >= 0
     if (n < 2)
         return n;
     else
         return fib(n-1) + fib(n-2);
 }

But without memoization this takes O(exp^N) operations with O(N) stack space.

It can be rewritten:

 function fib(n)
 {
     if (n < 2)
        return n;
     var a = 0, b = 1;
     while (n > 1)
     {
         var tmp = a;
         a = b;
         b = b + tmp;
         n = n - 1;
     }   
     return b;
 }

But this involves knowledge of how the function works, not sure if it can be generalized to an automatic process.

like image 24
Jason S Avatar answered Sep 29 '22 17:09

Jason S