Recursion
Recursion
Introduction
• A recursive algorithm is one that is defined in terms of itself. This means that,
when the steps of the algorithm are written down, one of the steps refers to
the same algorithm by name. When implemented, the subroutine will
include one or more calls to the original algorithm.
• Recursion is a method of solving a problem where the solution depends on
solving increasingly smaller instances of the same problem.
• The subroutine is defined with a single parameter, n. This value will be used
as the upper bound of the range. If the subroutine is called with the
argument 5, sum_to_n(5), the output would be 15. This is because 1, plus, 2,
plus, 3, plus, 4, plus, 5, equals, 15,1+2+3+4+5=15
Question:
On which line is the recursive call made?
Question:
• Which line expresses the base case?
Step 1
A stack frame for the first call of the subroutine is pushed on to the call stack.
This includes the value for n,n, which is 5. The subroutine runs to line 5 and then
calls itself with the argument value of n, minus, 1,n−1, which in this case is 4. The
return address of 5* is updated on the stack frame.
Step 2
A stack frame for the second call of the subroutine is pushed on to the call
stack. This includes the value for n,n, which is 4. The top of stack pointer is
incremented by 1. The subroutine runs to line 5 and then calls itself with the
argument value 3. The return address of 5* is updated on the current stack
frame.
Step 3
A stack frame for the third call of the subroutine is pushed on to the call stack.
This includes the value for n,n, which is 3. The top of stack pointer is incremented
by 1. The subroutine runs to line 5 and then calls itself with the argument value
2. The return address of 5* is updated on the current stack frame.
Step 5
A stack frame for the fifth call of the subroutine is pushed on to the call stack.
This includes the value for n,n, which is 1. The top of stack pointer is incremented
by 1.
Step 6
The subroutine checks the condition at line 2. This evaluates as 'True', so the
subroutine returns 1. The return statement causes the subroutine to terminate.
The frame is popped from the call stack and the top of stack pointer is
decremented by 1.
Step 8
Control returns to the subroutine at the top of the stack and it goes back to line
5. This line can now complete by taking the value of n,n, which is 3, from the
stack frame and adding 3 (the value that was returned at the previous step).
The result — 6 — is returned. The return statement causes the subroutine to
terminate. The frame is popped from the call stack and the top of stack pointer
is decremented by 1.
Step 9
Control returns to the subroutine at the top of the stack and it goes back to line
5. This line can now complete by taking the value of n,n, which is 4, from the
stack frame and adding 6 (the value that was returned at the previous step).
The result — 10 — is returned. The return statement causes the subroutine to
terminate. The frame is popped from the call stack and the top of stack pointer
is decremented by 1.
Before you move on, make sure that you can follow this step-by-step trace with
confidence. The diagram below shows another way that the flow of calls and
returns can be represented. If you have to trace a recursive subroutine, you
may find one (or both) of these methods useful.
This time there is only a single function call. A loop is used to handle the
successive values of n,n.
Question:
Answer: 4 times
• The call stack, like any stack, is finite in size. Memory space is allocated for
the call stack before the program is run. In some low-level languages, the
amount of memory allocated is determined by the programmer. In high-
level languages, it is controlled by the program language variables, the
compiler, and/or the operating system.
• If you write a subroutine that calls itself with no means of escape, you will fill
up the stack with hundreds of stack frames. This will eventually result in the
infamous stack overflow error message.
Stack Frames
• When a subroutine is called, a stack frame is created with memory space
allocation for:
o The values of any local variables
o The values of any parameters
• It also holds a reference to the 'execution point' of the subroutine; think of
this as the line number where program control needs to return to if another
subroutine is called. Sometimes this is called the return pointer.
• To see how the call stack and stack frames are used, consider this program
that is made up of two subroutines.