In programming, weāve seen that we can use loops to repeat an operation. We call these iterative loops. Weāre now going to take a more detailed look at a concept we touched on earlier in the courseārecursion.
Itās a very specific concept. Have you ever dreamed you were dreaming? Thatās more or less it! Itās all about concepts which refer to themselves. Letās find out more!
Recursion is a concept which works by referring back to itself.
Russian dolls are an excellent metaphor for recursion. Each doll is the same, except for its size, and each doll opens up to reveal a smaller doll inside it, until you get to the smallest one in the center, which doesnāt open. When you reach the smallest doll, you go through the whole process again, closing each doll in the opposite order.
In actual fact, we use recursion every day when we speak! We use words to define other words, which themselves are defined by other words.
In programming, we can talk about recursion when a function refers back to itself. When two functions call each other, this is known as mutual recursion.
Letās try to transcribe the example of the Russian dolls using a recursive function. Weāre going to use it to count the number of dolls.
First, we need to create a function which takes a doll as a parameter, whether or not it contains another doll:
Number_of_dolls(doll) algorithm
Start
EndNow we can create the body of the function. If the doll used as a parameter contains another doll, we return 1 to count this doll, and we call the same function recursively to check if the other doll also contains a doll.
Number_of_dolls(doll) algorithm
Start
If doll contains another doll:
Return 1 + number_of_dolls(doll inside)
End If
EndTo finish, we need to find a way of stopping this recursive function, otherwise weāll end up with an infinite loop. If the doll doesnāt contain another doll, we want the function to simply return 1 to count it, and then stop.
This is the complete function:
Number_of_dolls(doll) algorithm
Start
If doll contains another doll:
Return 1 + number_of_dolls(doll inside)
Else
Return 1
End If
EndLike with loops, we always need to add a condition to stop recursive calls.Ā
Anyone whoās ever had a job interview for a role as a developer will certainly have heard of the Fibonacci sequence! One of the most common problems candidates are asked to solve in interviews is āgiven an input n, find the nth number in the Fibonacci sequence.ā
The Fibonacci sequence is a list of whole numbers. It generally starts with the numbers zero and one (or sometimes one and one). Numbers in this list are called terms. Each term is the sum of the two previous terms.
For example, if we take the start of the Fibonacci sequence: 0, 1, 1, 2, 3, 5, 8, 13, 21, etc., you can see that 0 + 1 equals 1, 1 + 2 equals 3, 2 + 3 equals 5, and so on.
Weāre going to use algorithms to solve the problem mentioned above: given an input n, find the nth number in the Fibonacci sequence. There are many ways of doing this. Take a few minutes to think about the different algorithms you could invent.
Weāll use a recursive method and an iterative method, so you can compare the two possibilities.
A naive algorithm is a āsimpleā algorithm, based on the most obvious solution that springs to mind to resolve a problem.
In our case, we can write:
Fibonacci(n) algorithm
Start
If n <= 1:
Return 1
Else
Return fibonacci(n - 1) + fibonacci(n - 2)
End If
EndIf we call the Ā fibonacciĀ function with the parameter as ā3ā Ā fibonacci(3)Ā , the function returns 3. But why?
fibonacci(3)Ā : calls the functions Ā fibonacci(2)Ā and Ā fibonacci(1)Ā :
fibonacci(1)Ā : this function stops and returns 1.
fibonacci(0)Ā : this function stops and returns 1.
So,Ā Ā fibonacci(2)Ā returns 1 + 1.
fibonacci(2)Ā : calls the functions Ā fibonacci(1)Ā and Ā fibonacci(0)Ā .
fibonacci(1)Ā : this function stops and returns 1.
Finally, we add up what Ā fibonacci(2)Ā and Ā fibonacci(1)Ā return, i.e., 2 + 1.Ā
So Ā fibonacci(3)Ā = 3.
The problem with this method is that it takes up a lot of memory. This is because itās an exponential calculationāit requires two different calculations to calculate itself.
When we calculate the value of a number, we carry out the three following operations:
Calculate fibonacci(n-1) [which itself calculates fibonacci (n-1) and so on until it gets to the figure 1] and store the value in the memory.Ā
Calculate fibonacci(n-2) [do the same each time until it gets to 1] and store the value in the memory.Ā
Finally, add the two values.Ā
We can see that this is an exponential calculationāeach new number requires twice as much memory as the previous one. Its complexity is .
How can we calculate it without taking up so much memory?
Thatās where linear algorithms come in useful!
What if you calculated two consecutive values, one after the other? That would be a better solution, wouldnāt it?
We can write the following function:
Fibonacci(n) algorithm
Variable
a ā 0 : INTEGER
b ā 1 : INTEGER
c ā 0 : INTEGER
Start
For i from 1 to n:
c ā a + b
a ā b
b ā c
Return b
EndEach new number now only needs one line of operations, rather than two. This algorithm is therefore linear, and its complexity is .
We can see here that, in many cases, itās better to use the iterative version, as it uses less memory. Recursion isnāt the solution to every problem!
Here are the important steps involved in programming a recursive function:
Break a problem down into one or more subproblems of the same type. The subproblems can be solved using recursive calls.Ā
Subproblems must be smaller than the initial problem.
Breaking down a problem should lead to a basic element which canāt be broken down into further subproblems. This is its base case.
Remember when we broke down each function call recursively for the Fibonacci sequence problem? We looked at the order in which each function was called to identify the final result of these recursive calls. The computer automatically stacks each function call to determine the right order, and know which functions are active. This is whatās known as a call stack.
The computer has to remember the result of all the recursive calculations before ending the loop. To do this, it uses a call stack, which is automatically generated by the system.
As an example, letās take a look at this function, Ā mainĀ , in the maze:
Main() algorithm
Variable
player_position_x ā 0 : INTEGER
player_position_y ā 0 : INTEGER
end_position_x ā 5 : INTEGER
end_position_y ā 5 : INTEGER
keys[3] : ARRAY STRING
Start
While player_position_x != end_position_x AND player_position_y != end_position_y AND keys.size() != 3:
moves(player_position_x, player_position_y)
pick_up(keys, player_position_x, player_position_y)
End While
EndĀ When the Ā mainĀ function is called, itās placed in the call stack:
main() |
It remains there for as long as itās active, i.e., until it ends.Ā
Then, in the Ā mainĀ function, we call the Ā movesĀ function a first time in the Ā whileĀ loop, and itās also added to the call stack, above the Ā mainĀ function.
moves(player_position_x, player_position_y) main() |
Straight after, the Ā movesĀ function ends, so itās āpopped,ā i.e., removed, from the stack:
main() |
On the following line, the Ā pick upĀ function is called, so itās āpushed,ā i.e., added to the stack. We now get this:
pick_up(keys, player_position_x, player_position_y) main() |
The Ā pick upĀ function is also popped when itās finished, and so on for as long as the loop is active. When the loop ends, the main function ends too. The Ā mainĀ function is then also popped from the call stack. When the stack is empty, the program is finished!
That is exactly what happens in the case of a recursive call!
Letās take a look at this recursive function:
Counter(n) algorithm
If n > 0 :
counter(n - 1)
End If
Display n
EndWhen we call the Ā counterĀ function with Ā n=2Ā , we get the following call stack:
push counter(2) | push counter(1) | push counter(0) |
counter(2) | counter(1) counter(2) | counter(0) counter(1) counter(2) |
All recursive calls within the Ā counterĀ function are pushed onto the call stack.
When the last recursive function is called, the computer āpopsā all of the functions from the call stack. In other words, it looks through the stack to find the last element saved, and so on until it gets to the bottom of the stack. This comes in very useful!
pop counter(0) | pop counter(1) | pop counter(2) |
counter(0) counter(1) counter(2) | counter(1) counter(2) | Ā |
Display 0 | Display 1 | Display 2 |

To finish our maze, weāre going to add a last feature. Weāre going to set some traps on certain squares, which will immobilize the player for 10 seconds when they land on them.
To do this, youāll need to create a recursive function which immobilizes the player for n seconds, and displays a countdown of the time left before theyāre set free again. Weāll call this function Ā freezeĀ .
Using the function Ā waitĀ , you can pause the game for a certain number of seconds. The number of seconds is passed as a parameter of the function.
Define a Ā freezeĀ function which takes the number of seconds of immobilization, n, as a parameter.Ā
Display the number of seconds remaining.
Pause the game for one second.
Recursively call the Ā freezeĀ function.
Specify the base case of the recursive function.
Hereās what the result of the exercise should look like:
Freeze(n) algorithm
If n == 0 :
stop the recursive call
End If
Display n
wait(1)
freeze(n - 1)
EndA recursive function is a function which calls itself during its execution.
The steps for creating a recursive function are:
Break the problem down into one or more subproblems of the same type. These will be solved using recursive calls.Ā
Subproblems must be smaller than the initial problem.
Finally, breaking down a problem must result in a basic element which canāt be broken down into further subproblems. This is the base condition.Ā
A call stack saves information on the active functions in a computer program.
You made itāthis is the end of the course! Well done for all your hard work! Thereās just one quiz left to put your new knowledge to the test. I know how much you love quizzes!