
Learn through the super-clean Baeldung Pro experience:
>> Membership and Baeldung Pro.
No ads, dark-mode and 6 months free of IntelliJ Idea Ultimate to start with.
Last updated: February 24, 2023
Recursion and iteration are the basic ways to execute a given set of instructions in programming languages repeatedly. Although recursion has its advantages, iterative algorithms are often preferred for their efficiency and space optimization.
In this tutorial, we’ll explore how to convert a recursive factorial function into an iterative one using the tail recursive method.
Recursion and iteration are two methods for repeatedly executing a set of instructions:
The simplest case to handle is tail recursion. Thus, the method recommended is to convert all recursive calls into tail calls.
Let’s take a look at how to make simple recursive calls into tail calls:
Let’s now take a look at the steps to convert a tail-recursive function into an iterative function:
With such a simple function, we could skip straight to the iterative version without utilizing any strategies. But the goal here is to create a mechanical process that we can rely on when our functions aren’t so straightforward. So, we’ll work on the factorial function to concentrate on the process.
The factorial function is a common example used to demonstrate recursion. Here’s an example of the factorial function using a recursive algorithm:
algorithm Factorial(n):
// INPUT
// n = a natural number
// OUTPUT
// n! = the factorial of n
if n < 2:
return 1
else:
return n * Factorial(n - 1)
In this step, we’ll convert the recursive call to a tail call. In short, we have only one problematic line , which we have to extend using an accumulator:
algorithm Factorial(n, acc = 1):
// INPUT
// n = a non-negative integer
// acc = the accumulator to hold the intermediate factorial results (default is 1)
// OUTPUT
// n! = the factorial of n
if n < 2:
return acc * 1
else:
return acc * n * Factorial(n - 1)
As a result, it computes the factorial of and then multiplies it by
. However, we don’t need to do the multiplication ourselves. Using the accumulator argument, we can now ask our extended factorial function to do it for us. The algorithm below presents the tail call after substituting the extended factorial function with
:
algorithm Factorial(n, acc = 1):
// INPUT
// n = a non-negative integer
// acc = the accumulator, initially set to 1
// OUTPUT
// n! = the factorial of n
if n < 2:
return 1 * acc
else:
return Factorial(n - 1, n * acc)
After converting the recursive call to a tail call, we can convert it to an iterative function by introducing a one-shot loop around the function body {
} :
algorithm Factorial(n, acc = 1):
// INPUT
// n = a natural number
// acc = the accumulator, default is 1
// OUTPUT
// n! = the factorial of n
while true:
if n < 2:
return 1 * acc
else:
return Factorial(n - 1, n * acc)
break // Let's follow the steps for now and we'll tidy the code later
Let’s now replace all the recursive tail calls with
:
algorithm Factorial(n, acc = 1):
// INPUT
// n = a natural number
// acc = the accumulator, default value is 1
// OUTPUT
// n! = the factorial of n
while true:
if n < 2:
return 1 * acc
else:
(n, acc) = (n - 1, acc * n)
continue
break
Let’s clean up the code and make it more appropriate:
algorithm Factorial(n, acc = 1):
// INPUT
// n = a natural number
// acc = the accumulator to store the intermediate results, default is 1
// OUTPUT
// n! = the factorial of n
while n > 1:
(n, acc) <- (n - 1, acc * n)
return acc
Here’s the build-up of stack frames using different methods to compute the factorial of 3:
Let’s discover the stack frames using factorial with recursion:
Here’s the build-up of stack frames using factorial with a tail call:
Here are the stack frames using factorial with iteration:
As we can see, when factorial is computing the factorial of 3, three frames build up on the stack. Same thing for the tail-recursive factorial. However, the iterative factorial uses just one stack frame, over and over, until it’s done. In short, we converted stack use into
stack use.
Here are some methods to convert a complex recursive function to a tail-recursive function:
After converting the recursive function to a tail recursive, we can follow the steps in section to make the iterative form of our function.
In this tutorial, we explored the difference between the recursive and iterative approaches. We also discussed converting a simple recursion into an iterative function using the tail-recursive approach. Then, we applied this strategy to the factorial function. We can use this method to optimize the performance of various recursive functions.