07 Recursion
07 Recursion
1
INDIAN INSTITUTE OF TECHNOLOGY KHARAGPUR
Recursion
• Either directly.
• F calls F.
• Or cyclically in a chain.
• F calls G, G calls H, and H calls F.
Used for repetitive computations in which each action is stated in terms of a previous result.
2
Basis and Recursion
3
Examples:
• Factorial:
fact(0) = 1
fact(n) = n * fact(n - 1), if n > 0
• GCD:
gcd (m, m) = m
gcd (m, n) = gcd (m%n, n), if m > n
gcd (m, n) = gcd (n, n%m), if m < n
4
Example 1 :: Factorial
5
Example 1 :: Factorial Execution
fact(4) 24
if (4 = = 1) return (1);
else return (4 * fact(3)); 6
if (3 = = 1) return (1);
else return (3 * fact(2)); 2
if (2 = = 1) return (1);
else return (2 * fact(1)); 1
int fact ( int n)
{ if (1 = = 1) return (1);
if (n = = 1) return (1);
else return (1 * fact(0));
else return (n * fact(n - 1) );
}
6
Example 2 :: Fibonacci number
Fibonacci number f(n) can be defined as:
f(0) = 0
f(1) = 1
f(n) = f(n - 1) + f(n - 2), if n > 1
• The successive Fibonacci numbers are:
0, 1, 1, 2, 3, 5, 8, 13, 21, …..
Function definition:
int f (int n)
{
if (n < 2) return (n);
else return ( f(n - 1) + f(n - 2) );
}
7
Tracing Execution
int f (int n)
{
f(4)
if (n < 2) return (n);
else return ( f(n - 1) + f(n - 2) ); f(3) f(2)
}
f(1) f(0)
Inefficiency:
• Same thing is computed several times. called 9 times
8
Notable Point
• Sometimes, if the function being computed has a nice recurrence form, then a recursive code may be more
readable
9
Important things to remember
• Think how the whole problem can be solved if you can solve the exact same problem on a smaller problem.
• But then, do NOT think how the smaller problem will be solved, just call the function recursively and assume it
will be solved.
11
int sumSquares (int m, int n)
Annotated Call Tree {
int middle ;
if (m == n) return(m*m);
else {
middle = (m+n)/2;
355 return (sumSquares(m,middle)
sumSquares(5,10) + sumSquares(middle+1,n));
}
245 }
110
sumSquares(5,7) sumSquares(8,10)
sumSquares(5,10)
61 49 145 100
sumSquares(5,6) sumSquares(7,7) sumSquares(8,9) sumSquares(10,10)
25 36 64 81
sumSquares(5,5) sumSquares(6,6) sumSquares(8,8) sumSquares(9,9)
25 36 49 64 81 100
12
Example: Printing the digits of an Integer in Reverse
Print the last digit, then print the remaining number in reverse
• Ex: If integer is 743, then reversed is print 3 first, then print the reverse of 74
13
Counting Zeros in a Positive Integer
14
Common Errors in Writing Recursive Functions
int anotherBadFactorial(int x) {
if(x == 0)
return 1;
else
return x*(x-1)*anotherBadFactorial(x-2);
// When x is odd, base case never reached!!
}
Common Errors in Writing Recursive Functions
Mixing up loops and recursion
int anotherBadFactorial(int x) {
int i, fact = 0;
if (x == 0)
return 1;
else {
for (i=x; i>0; i=i-1) {
fact = fact + x*anotherBadFactorial(x-1);
}
return fact;
}
}
In general, if you have recursive function calls within a loop, think carefully if you need it.
Most recursive functions you will see in this course will not need this
Example :: Towers of Hanoi Problem
The problem statement:
• Initially all the disks are stacked on the LEFT pole.
• Required to transfer all the disks to the RIGHT pole.
• Only one disk can be moved at a time.
• A larger disk cannot be placed on a smaller disk.
• CENTER pole is used for temporary storage of disks.
1
2
3
4
5
18
Phase-1: Move top n – 1 from LEFT to CENTER
1
2
3
3 2 1
LEFT CENTER RIGHT
1
3 2
1
3 2
1
2 3
20
Phase-3: Move top n – 1 from CENTER to RIGHT
1
2 3
1 2 3
1
2
3
main( )
{ int n; /* Number of disks */
scanf (“%d”, &n);
transfer (n, ‘L’, ‘R’, ‘C’);
}
22
With 3 discs
With 4 discs
23
Recursion versus Iteration
Repetition
Balance
24
More Examples
25
INDIAN INSTITUTE OF TECHNOLOGY KHARAGPUR
What do the following programs print?
26
INDIAN INSTITUTE OF TECHNOLOGY KHARAGPUR
Printing cumulative sum -- will this work?
27
INDIAN INSTITUTE OF TECHNOLOGY KHARAGPUR
Printing cumulative sum (two ways)
int foo( int n )
void foo( int n, int sum )
{
{
int data, sum ;
int data ;
if ( n == 0 ) return 0;
if ( n == 0 ) return 0;
sum = foo ( n – 1 );
Input: 123 4 5 scanf(“%d”, &data);
scanf(“%d”, &data);
sum = sum + data;
sum = sum + data; Output: 1 3 6 10 15 printf(“%d\n”, sum);
printf(“%d\n”, sum);
foo( k – 1, sum ) ;
return sum;
}
}
main ( ) {
main ( ) {
int k = 5;
int k = 5;
foo ( k, 0 );
foo ( k );
}
}
28
INDIAN INSTITUTE OF TECHNOLOGY KHARAGPUR
Paying with fewest coins
29
INDIAN INSTITUTE OF TECHNOLOGY KHARAGPUR
Paying with fewest coins
30
INDIAN INSTITUTE OF TECHNOLOGY KHARAGPUR
Paying with fewest coins
31
INDIAN INSTITUTE OF TECHNOLOGY KHARAGPUR
Practice Problems
Note:
• For each of the above, write the main functions to call the recursive function also
• Practice problems are just for practicing recursion, recursion is not necessarily the most efficient way
of doing them
32
Advanced topic
33
INDIAN INSTITUTE OF TECHNOLOGY KHARAGPUR
How are recursive calls implemented?
34
• Activation records keep popping off, when the termination condition of recursion is reached.
Local
Variables
Return Value
Return Addr
35
Example:: main( ) calls fact(3)
main()
{
int n;
n = 3;
printf (“%d \n”, fact(n) );
int fact (n)
}
int n;
{
if (n = = 0)
return (1);
else
return (n * fact(n-1));
}
36
TRACE OF THE STACK DURING EXECUTION
n=0
1
RA .. fact
n=1 n=1 n=1
fact( )
main( ) - - 1*1 = 1 returns
calls RA .. fact RA .. fact RA .. fact to main( )
fact( ) n=2 n=2 n=2 n=2 n=2
- - - - 2*1 = 2
RA .. fact RA .. fact RA .. fact RA .. fact RA .. fact
n=3 n=3 n=3 n=3 n=3 n=3 n=3
- - - - - - 3*2 = 6
RA .. main RA .. main RA .. main RA .. main RA .. main RA .. main RA .. main
37
Do Yourself
Trace the activation records for the following version of Fibonacci sequence.
#include <stdio.h>
int f (int n)
{
int a, b;
if (n < 2) return (n); Local
Variables
else {
X a = f(n-1); (n, a, b)
Y b = f(n-2); Return Value
return (a+b); } Return Addr
} (either main,
or X, or Y)
main( ) {
printf(“Fib(4) is: %d \n”, f(4));
}
38