You are on page 1of 32

Recursion

Programming II

Faculty of
Computer Science
Faculty of Computer Science

Index

• What is recursion?

• How recursion works

• Developing recursive programs: the induction method

• Exercises

Recursion 2
What is recursion?

Programming II

Faculty of
Computer Science
Faculty of Computer Science

Recursive Algorithm: definition

• That one that expresses the solution of a problem in


terms of a call to itself (recursive call).
• If the first call tries to solve a problem of size N, every
new (recurring) execution will try to solve a problem
of the same nature as the original one but with a
smaller size.
• Thus, at some point its solution will become trivial (or,
at least, manageable enough so it can be solved in a
non-recursive way). In this case we will say that we
are dealing with a base case of recursion.

Recursion 4
Faculty of Computer Science

Keys for recursion

• Therefore, to build a recursive subprogram:


– Each new call should be defined on a problem of less
complexity (thus easier to solve) than the original one.

– There must be at least one base case (thus ending the


recursion process) in order to avoid infinite recursion.

Recursion 5
Faculty of Computer Science

Parts of a recursive solution

• Base case(s), in which the problem is simple enough


to be solved directly, without recursion.
• Recursive step(s):
– Divides the problem into one or more much simpler
problems or into smaller parts of the problem,

– calls the function (recursively) on each part, and

– combines the solutions obtained for each part into a solution


to the entire problem.

Recursion 6
Faculty of Computer Science

Recursion vs. Iteration


• Both involve repetition: iteration uses a repetitive
structure (a loop); recursion is achieved by making
repeated calls.
• Both finish when the termination test is satisfied (exit
condition):
 Iteration ends when the loop condition is not met anymore.
 Recursion ends when a base case is recognized.
• Recursion demands more computational resources.

Recursion 7
Faculty of Computer Science

Use recursion when...

• The problem is complex and has a recursive


nature.
• It provides a more natural solution to the
problem and a program that is easier to
understand and debug.
• An iterative solution is not clear or obvious.

Recursion 8
Faculty of Computer Science

As a summary…

• Any problem that can be resolved recursively can


also be solved iteratively (i.e. not recursively).

• When time and memory costs are critical, the solution


to be chosen must be the iterative one instead.

Recursion 9
How recursion works

Programming II

Faculty of
Computer Science
Faculty of Computer Science

Stack and Activation Records


• Every function call creates an activation record (AR)
(a.k.a. stack frame).
• An AR is the piece of memory where the system holdsthe
values of the constants, variables and pass-by-value
parameters of the subroutine currently in execution.
• If function A calls function B, the execution of A is stopped
at the instruction where B is called. Its AR is used to store
the address following the call instruction, named return
address, along with the local data being handled at that
moment.
• Once a function ends, its AR is destroyed.
• Ars are stored in the so-named [Call] Stack.

Recursion 11
Faculty of Computer Science

Recursion: call process

• Let's assume that we have the following recursive code:

unsigned long int Factorial(unsigned int n)


{
if n == 0
return(1);
else Return address
return(n * Factorial(n-1)); R2
}

• Now, we will analyse how the following call works:


Return address
Result = Factorial(3); R1

Recursion 12
Faculty of Computer Science

Factorial(3)
Stack status

Result ?
n 3 First call
Return address R1

Activation
Memory
record (Stack)
Recursion 13
Faculty of Computer Science

Factorial(3) = 3*Factorial(2)
Stack status

Result ?
n 2 Second call
Return address R2
?
3 First call
R1

Memory
Recursion 14
Faculty of Computer Science

Factorial(2) = 2*Factorial(1)

Result ?
Stack status

n 1 Third call
Return address R2
?
2 Second call
R2
?
3 First call
R1

Memory
Recursion 15
Faculty of Computer Science

Factorial(1) = 1*Factorial(0)

Result 1
n 0 Fourth call
Return address R2
?
Stack status

1 Third call
R2
?
2 Second call
R2
?
3 First call
R1

Memory
Recursion 16
Faculty of Computer Science

Return

Result 1
Stack status

n 1 Third call
Return address R2
?
2 Second call
R2
?
3 First call
R1

Memory
Recursion 17
Faculty of Computer Science

Return
Stack status

Result 1
n 2 Second call
Return address R2
?
3 First call
R1

Memory
Recursion 18
Faculty of Computer Science

Return
Stack status

Result 2
n 3 First call
Return address R1

Memory
Recursion 19
Faculty of Computer Science

End

• Execution of call Factorial(3) ends. The program returns


to instruction R1 and continues its execution from there.

Result 2
n 3
Return address R1 Result = 6

Memory

Recursion 20
Faculty of Computer Science

Recursive calls and


returns through time

time

Recursion 21
Faculty of Computer Science

To begin with …

• Let’s take the following function P:


void P(int num)
{
if ((num>=1) && (num <=8)){
P(num-1);
printf(" %i ", num);
}
else
printf("\n");
}

• What is the output returned for P(3), P(7), P(10)?

Recursion 22
Faculty of Computer Science

To begin with …

• What are we computing with the following recursive


function F? (assuming n>=0)

float F (float x, unsigned int n)


{
if (n == 0)
return(0);
else
return(x + F (x, n-1));
}

Recursion 23
Developing recursive
programs:
the induction method

Programming II

Faculty of Computer Science


Faculty of Computer Science

Steps for the development


of recursive code
1. To redefine the original problem in recursive terms:
Induction Method.

2. To write the recursive code.

3. To verify the recursive code.

4. To validate the recursive code.

Recursion 25
Faculty of Computer Science

Step 1: Induction Method


Commonly used in Mathematics for theorem proving (Mathematical
Induction). It consists of three phases:
• Example: prove that "Every integer number n>=1 of the form 10n-1 is divisible
by 9".

1. Induction basis: Identify base cases (i.e. trivial cases with direct
solution):
 n=1 meets 101-1 = 10-1 = 9 = 9*1
2. Establish the induction hypothesis: Assume that the property is
fulfilled for a case simpler than the general one (n):
 assume that n-1 meets 10(n-1)-1 = 9*a
3. Induction step: Using the hypothesis, we prove the general case:
 since 10(n-1)-1 = 9*a we can prove that it is true for all n:
10n-1 = 10*10(n-1)-(10-9) = 10*10(n-1)-(10-9) = (10*10(n-1)-10)+9 =
= 10*(10(n-1)-1)+9 = 10*(9*a)+9 = 9*(10*a+1) = 9*b
Recursion 26
Faculty of Computer Science

Step 1: Induction Method (cont.)

Also applicable to programming.


• Example: recursive implementation of
int Factorial (int n) (PreCD: n>=0)

1. Base cases: Identify trivial cases with direct solution:


 if n=0 then Factorial=1
2. Induction hypothesis: Let's assume that the function Factorial() we try to
build already works for cases simpler than the general:
 Hypothesis: Factorial(n-1) returns (n-1)! correctly
3. General case: We obtain the general case using our previous hypothesis.
 Factorial(n) = n * Factorial(n-1)

Here it is our recursive solution!

Recursion 27
Faculty of Computer Science

Step 2: Writing the recursive code

• We build the code as a sequence of if-then-else


where the base cases are checked first and, next, the
general case:

1 unsigned long int Factorial(unsigned int n){


2 if (n == 0)
3 return(1);
4 else
5 return(n * Factorial(n-1));
6 }

Recursion 28
Faculty of Computer Science

Step 3: Verifying the recursive code

• We verify that the code is well-constructed and that


infinite recursion is not possible:
a) There are base cases that are solved without recursion.
b) All recursive calls get closer and, finally, reach a base case.

long int Factorial (int n) void recursive(int n);


{ { Non-recursive
if (n==0) Non-recursive if (n==0) { case is present
case is present
return(1); Printf(“End reached”);
else return;
return(n * Factorial(n-1)); }
} else
return(recursive(trunc(n/2) + 1));
Recursive case always reach
}
Recursive case never reaches
the non-recursive case
the non-recursive one if n>0

Recursion 29
Faculty of Computer Science

Step 4: Validating the recursive code

• We verify that the code returns the right result by


simulating the execution and its activation records.
Example: Factorial(3)

Return
Parameter n Stop instruction
value
3 5 Factorial = 3 *Factorial(2); 6
2 5 Factorial = 2 *Factorial(1); 2
1 5 Factorial = 1 *Factorial(0); 1
0 -- 1

Recursion 30
Faculty of Computer Science

Recursive or Iterative?

• Questions to be considered when deciding how to


implement a solution:
– Computational cost (CPU time and memory): in general, recursion
increases costs.
– Redundancy: some recursive solutions involve repeated calls, thus
causing redundant calculations.
e.g. Fibonacci(n) = Fibonacci(n-1) + Fibonacci(n-2)
– Complexity of the solution: sometimes, the recursive solution is
easier to find than the iterative one (e.g. towers of Hanoi)
– Conciseness, legibility and elegance of the resulting code: the
recursive solution may be simpler.

Recursion 31
Recursion: Exercises

Programming II

Faculty of Computer Science

You might also like