2016 CCP CH 11 Final Recursion
2016 CCP CH 11 Final Recursion
11.1 Recursion
Recursion is a powerful tool but least understood by most novice students.
Programming languages such as Pascal, C, C++ etc support recursion. Now, let us see
“What is recursion? What are the various types of recursion?”
Definition: A recursion is a method of solving the problem where the solution to a
problem depends on solutions to smaller instances of the same problem. Thus,
recursion is a way to decompose a given task into smaller subtasks of same type
where:
¨ Each subtask is a smaller example of the same task.
¨ The smallest example of the task has a non-recursive solution.
A recursive function is a function that calls itself during execution. This enables the
function to repeat itself several times to solve a given problem. The various types of
recursion are shown below:
Direct recursion
Indirect recursion
Direct recursion: A recursive function that invokes itself is said to have direct
recursion. For example, the factorial function calls itself (detailed explanation is given
later) and hence the function is said to have direct recursion.
return n*fact(n-1);
}
¨ Indirect recursion: A function which contains a call to another function which in
turn calls another function which in turn calls another function and so on and
11. 2 : C programming Techniques
eventually calls the first function is called indirect recursion. It is very difficult to
read, understand and find any logical errors in a function that has indirect
recursion. For example, a function f1 invokes f2 which in turn invokes f3 which in
turn invokes f1 is said to have indirect recursion. This is pictorially represented as
shown below:
void f1() void f2() void f3()
{ { {
…… …… F1();
…… F3(); …… Indirect recursion
f2(); …… ……
} } }
Definition: A base case is a special case where solution can be obtained without
using recursion. This is also called base/terminal condition. Each recursive function
must have a base case. A base case serves two purposes:
1) It acts as terminating condition.
2) The recursive function obtains the solution from the base case it reaches.
For example, in the function factorial, 0! is 1 is the base case or terminal condition.
Definition: In any recursive function, the part of the function except base case is
called general case. This portion of the code contains the logic required to reduce the
size (or instance) of the problem so as to move towards the base case or terminal
condition. Here, each time the function is called, the size (or instance) of the problem
is reduced. For example, in the function fact, n*fact(n-1) is general case. By
decreasing the value of n by 1, the function fact is heading towards the base case.
So, the general rules that we are supposed to follow while designing any recursive
algorithm are:
¨ Determine the base case. Careful attention should be given here, because: when
base case is reached, the function must execute a return statement without a call to
recursive function.
¨ Determine the general case. Here also careful attention should be given and see
that each call must reduce the size of the problem and moves towards base case.
¨ Combine the base case and general case into a function.
Functions and program structure : 11. 3
Note: A recursive function should never generate infinite sequence of calls on itself.
An algorithm exhibiting this sequence of calls will never terminate and hence it is
called infinite recursion and will crash the system.
5! = 5 * 4!
4! = 4 * 3! Decompose the
3! = 3 * 2! problem from
2! = 2 * 1! top to bottom
1!= 1 * 0!
1! = 1 * 0! = 1
2! = 2 * 1! = 2 Compute the
3! = 3 * 2! = 6 solution from
4! = 4 * 3! = 24 bottom to top
5! = 5 * 4! = 120
Design: Now, let us see “How to design any recursive function?” Let us take an
example of factorial function that uses recursion. Any recursive function has two
elements: base case and general case.
¨ Base case: The statement that solves the problem is called base case. Every
recursive function must have at least one base case. It is a special case whose
solution can be obtained without using recursion. A base case serves two
purposes:
1) It acts as terminating condition.
2) The recursive function obtains the solution from the base case it reaches.
n! = 1 if n == 0
11. 4 : C programming Techniques
¨ General case: The statement that reduces the size of the problem is called general
case. This is done by calling the same function with reduced size. It contains the
logic necessary to reduce the size of the problem. For example, while we compute
5!, initial size of the problem is 5 and then the problem is reduced to find 4!, 3!,
2!, 1! and finally we reached the base case 0! where 0! is 1. The general case can
be written by looking at the problem size. It is given that we need to find 5! which
can be written as shown below:
i.e., 5! = 5 * 4!
In general, n! = n * (n-1)! if n != 0
Thus, by looking at the base case and general case, the recursive definition to find
factorial of n can be written as shown below:
n!= 1 if n == 0 1 if n == 0
or n! =
n! = n * (n-1)! otherwise n * (n-1)! otherwise
1 if n == 0
F(n) = Output: 5 * 4 * 3 *2 * 1
n * F(n-1) otherwise
void main()
{
int n;
float res; Input
printf("Enter n and r\n"); Enter n and r
scanf("%d %d",&n, &r); 6 3
res = fact(n) / ( fact(n-r) * fact(r)); Output
6
printf("%dC%d = %d\n",n, r, res) C3 = 20
}
Note: Comparing iterative function (section 8.3.9) and above recursive function we
know that
¨ Recursive function is much simpler.
¨ No loops are present. Only simple if statement which returns either 1 or
product of two values using recursion. Looping is done recursively.
11.1.2 How recursion works
Let us visualize how the same function is called repeatedly using recursion. The
figure shows exactly what happens when recursive function fact() gets called. The
execution sequence for the above factorial function is shown below:
void main()
{
int n;
n = fact (3); a
printf("%d\n”, n);
}
3 2 1 0
int fact(int n) int fact(int n) int fact(int n) int fact(int n)
{ { { {
if ( n == 0 ) if ( n == 0 ) if ( n == 0 ) if ( n == 0 )
b c d 1
return 1; return 1; return 1; return 1;
return n* fact(n-1); return n* fact(n-1); return n* fact(n-1); return n* fact(n-1);
} 3*2 } 2*1 } 1*1 }
2 1
h g f e
5! = 5 * 4!
4! = 4 * 3! General case Decompose the
3! = 3 * 2! problem from top
2! = 2 * 1! to bottom
1!= 1 * 0!
1! = 1 * 0! = 1
2! = 2 * 1! = 2 Compute the
3! = 3 * 2! = 6 solution from
4! = 4 * 3! = 24 General case bottom to top
5! = 5 * 4! = 120
Functions and program structure : 11. 7
Now, let us see “What are the rules for designing any recursive function?”
The general rules that we are supposed to follow while designing any recursive
function are:
¨ Determine the base case. Careful attention should be given here, because: when
base case is reached, the function must execute a return statement without a call to
recursive function.
¨ Determine the general case. Here also careful attention should be given and see
that each call must reduce the size of the problem moving towards base case.
¨ Combine the base case and general case into a function.
F(4) = 4 + F(3)
F(3) = 3 + F(2) General case
F(2) = 2 + F(1) F(n) = n + F(n-1)
F(1) = 1 + F(0)
F(0) = 0 + F(-1)
F(0) = 0 + F(-1)
F(1) = 1 + F(0)
F(2) = 2 + F(1)
F(3) = 3 + F(2)
F(4) = 4 + F(3)
0 if n == -1
F(n) =
n + F(n-1) otherwise
11. 8 : C programming Techniques
// 4 + 3+ 2 + 1 + 0 where n = 4 // 0 + 1 + 2 + 3 + 4 where n = 4
int F(int n) int F(int n)
{ {
if ( n == -1 ) return 0; OR if ( n == -1 ) return 0;
Note: If we exchange the terms in the expression n + F(n-1) shown using dotted
rectangular box as: F(n-1) + n, we get the sum of the series: 0 + 1 + 2 + 3 + 4.
Note: By inserting an array a as the parameter and changing n to a[n] for the above
recursive relation, we get sum of following series:
0 if n == -1
F(a,n) =
a[n] + F(a, n-1) otherwise
Example 11.4: Recursive function to find sum of array elements from a[n-1] to a[0]
// sum = a[4] + a[3] + a[2] + a[1] + a[0] // sum = a[0] + a[1] + a[2] + a[3] + a[4]
float F(float a[], int n) float F(float a[], int n)
{ {
if ( n == -1 ) return 0; if ( n == -1 ) return 0;
Note: The expression a[n] + F(a, n-1) can be written as F(a, n-1) + a[n]. If we use the
expression a[n] + f(a, n-1) we get the sum of a[4] + a[3] + a[2] + a[1] + a[0]. But, if
Functions and program structure : 11. 9
we use the expression f(a, n-1) + a[n] we get sum of a[0] + a[1] + a[2] + a[3] + a[4].
The complete program can be written as shown below:
Note: Changing a[n] to “print a[n]” and removing the + symbol in the above program,
we can print array elements. So, the recursive definition to print array elements in
reverse order can be written as shown below:
0 if n == -1
F(a,n) =
print(a[n]) , F(a, n-1) otherwise Output: 50 40 30 20 10
Note: Replacing name of function F() to PrintArray(), we can write the function as
shown below:
Example 11.6: Recursive function to print array elements from a[0] to a[n-1]
Eercises:
1) What is recursion? What are the types of recursion?
2) Write a recursive function to find the factorial of a number
3) Write a recursive function to find binomial co-efficient.
4) Write a recursive function to find the sum of natural numbers.
5) Write a recursive function to find the sum of elements of the array
6) Write a recursive function to print the array elements in reverse order