Recursion
A function that calls itself
Recursion
• A function which calls itself is said to be recursive.
• Recursion is a technique which will allow us to solve certain problems that would be difficult to solve in other ways.
Recursion
• To illustrate recursion, let's consider the mathematical concept of factorial (the expression n! is read "n factorial").
• Here are two ways to define the factorial of a non-negative integer n:
Recursion
• Note that 0! is defined to be 1.
• Note also that in the recursive definition, factorial is defined in terms of itself!
Recursion
• Using the iterative definition, we would calculate 5! as
Recursion
• Using the iterative definition, we would calculate 5! as
5! = 1 * 2 * 3 * 4 * 5 = 120
Recursion
• Using the iterative definition, we would calculate 5! as
5! = 1 * 2 * 3 * 4 * 5 = 120 • Using the recursive definition, 5! is calculated as
5! = 5 * 4!
= 5 * 4 * 3!
= 5 * 4 * 3 * 2!
= 5 * 4 * 3 * 2 * 1!
= 5 * 4 * 3 * 2 * 1 * 0!
= 5 * 4 * 3 * 2 * 1 * 1
= 120
Recursion
• Here is a C++ function that implements the iterative definition of factorial. Note that it uses a loop to do the iteration:
int Factorial(int n) { int result = 1; for (int i = 1; i <= n; i++) { result *= i; } return result; }
Recursion
• Here is a C++ function that implements the recursive definition of factorial. Note that it contains no loop:
int RecursiveFactorial(int n) {if (n == 0) {
return 1; }else {
return n * RecursiveFactorial(n - 1);}
Recursion
• RecursiveFactorial illustrates the structure that is common to all recursive functions:
Recursion
• RecursiveFactorial illustrates the structure that is common to all recursive functions:
– First, a stopping condition is checked.
Recursion
• RecursiveFactorial illustrates the structure that is common to all recursive functions:
– First, a stopping condition is checked.
– This is called the base case.
Recursion
• RecursiveFactorial illustrates the structure that is common to all recursive functions:
– First, a stopping condition is checked.
– This is called the base case.
• In the case of RecursiveFactorial, the base case is n == 0.
Recursion
• RecursiveFactorial illustrates the structure that is common to all recursive functions:
– First, a stopping condition is checked.
– This is called the base case.
• In the case of RecursiveFactorial, the base case is n == 0.
– If the base case test evaluates to true, recursion ends with the return of the value 1.
Recursion
• RecursiveFactorial illustrates the structure that is common to all recursive functions:
– First, a stopping condition is checked.
– This is called the base case.
• In the case of RecursiveFactorial, the base case is n == 0.
– If the base case test evaluates to true, recursion ends with the return of the value 1.
– If the base case condition is false, an expression involving a recursive call is returned.
Recursion
• RecursiveFactorial illustrates the structure that is common to all recursive functions:
– First, a stopping condition is checked.
– This is called the base case.
• In the case of RecursiveFactorial, the base case is n == 0.
– If the base case test evaluates to true, recursion ends with the return of the value 1.
– If the base case condition is false, an expression involving a recursive call is returned.
• In the case of RecursiveFactorial, the returned expression is n * RecursiveFactorial(n - 1).
The figure below illustrates how RecursiveFactorial calculates the value of 3!:
Recursion
• By the way, recursion is not the technique to use for calculating the factorial of n.
– The iterative factorial function is much more efficient and should be used instead.
– This example was used because its recursive calculation is easy to implement and understand.
• As you continue your study of computer science you will see some very elegant recursive solutions to problems.
As a second example of a recursive function, let’s look at the following recursive definition for an:
This definition is implemented as the Power function, which returns an integral power of a number:
double Power(double base, int expo){
if (0 == expo) {
return 1.0; // x0 = 1
} else {
double semi = Power(base,expo/2);
if (expo % 2 == 0) { // even exponent return semi * semi;
} else { // odd exponent
return base*semi*semi;
}
}
}
Recursion
• Note again that, like all "good" recursive functions, Power begins by testing a stopping condition.
Recursion
• Note again that, like all "good" recursive functions, Power begins by testing a stopping condition.
– Only if the stopping condition is false does Power call itself recursively.
Here are general rules for writing recursive functions:
1. Identify a base case that does not make any recursive calls.
– Each call should make progress toward reaching the base case;
– this ensures termination since the function will end.
Here are general rules for writing recursive functions:
1. Identify a base case that does not make any recursive calls.
– Each call should make progress toward reaching the base case;
– this ensures termination since the function will end.
2. Solve the problem by making recursive calls that are similar but simpler (i.e., that move toward the base case).
– The similarity ensures that the recursion works:
– you'll be solving a similar problem.
Here are general rules for writing recursive functions:
1. Identify a base case that does not make any recursive calls.
– Each call should make progress toward reaching the base case;
– this ensures termination since the function will end.
2. Solve the problem by making recursive calls that are similar but simpler (i.e., that move toward the base case).
– The similarity ensures that the recursion works:
– you'll be solving a similar problem.
Note that RecursiveFactorial and Power satisfy both rules.
Okay, let's see how well you understand recursion:
• Determine the values returned by each of the following function calls by hand-executing the functions:
int Problem1(int n) {
if (n <= 1)
return 0;
else
return 1 + Problem1(n - 2);
}
Okay, let's see how well you understand recursion:
int Problem1(int n) {
if (n <= 1)
return 0;
else
return 1 + Problem1(n - 2);
}
What value is returned from the calls
a. Problem1(8)
b. Problem1(13)
c. Problem1(x), where x is a nonnegative integer
Problem1(8)
int Problem1(int n) {
if (n <= 1) return 0;
else
return 1 + Problem1(n-2);
}
Problem1(8) = 1 + Problem1(6)
= 1 + 1 + Problem1(4)
= 1 + 1 + 1 + Problem1(2)
= 1 + 1 + 1 + 1 + Problem1(0)
= 1 + 1 + 1 + 1 + 0
= 4
Okay, let's see how well you understand recursion:
int Problem1(int n) {
if (n <= 1)
return 0;
else
return 1 + Problem1(n - 2);
}
What value is returned from the calls
a. Problem1(8) = 4
b. Problem1(13)
c. Problem1(x), where x is a nonnegative integer
Problem1(13)
int Problem1(int n) {
if (n <= 1) return 0;
else
return 1 + Problem1(n-2);
}
Problem1(13) = 1 + Problem1(11)
= 1 + 1 + Problem1(9)
= 1 + 1 + 1 + Problem1(7)
= 1 + 1 + 1 + 1 + Problem1(5)
= 1 + 1 + 1 + 1 + 1 + Problem1(3)
= 1 + 1 + 1 + 1 + 1 + 1 + Problem1(1)
= 1 + 1 + 1 + 1 + 1 + 1 + 0
= 6
Okay, let's see how well you understand recursion:
int Problem1(int n) {
if (n <= 1)
return 0;
else
return 1 + Problem1(n - 2);
}
What value is returned from the calls
a. Problem1(8) = 4
b. Problem1(13) = 6
c. Problem1(x), where x is a nonnegative integer
Okay, let's see how well you understand recursion:
int Problem1(int n) {
if (n <= 1)
return 0;
else
return 1 + Problem1(n - 2);
}
What value is returned from the calls
a. Problem1(8) = 4
b. Problem1(13) = 6
c. Problem1(x), where x is a nonnegative integer = x/2
Greatest Common Divisor
int Problem2(int m, int n) {
if (m == n)
return m;
else if (m < n)
return Problem2(n - m, m);
else
return Problem2(m - n, n)
}
Greatest Common Divisorint Problem2(int m, int n) {
if (m == n)
return m;
else if (m < n)
return Problem2(n - m, m);
else
return Problem2(m - n, n)
}
What value is returned from the calls
a. Problem2(12, 8)
= Problem2(4, 8)
= Problem2(4, 4)
= 4
Greatest Common Divisorint Problem2(int m, int n) {
if (m == n)
return m;
else if (m < n)
return Problem2(n - m, m);
else
return Problem2(m - n, n)
}
What value is returned from the calls
b. Problem2(18, 24)
= Problem2(6, 18)
= Problem2(6, 12)
= Problem2(6, 6)
= 6
Greatest Common Divisorint Problem2(int m, int n) {
if (m == n)
return m;
else if (m < n)
return Problem2(n - m, m);
else
return Problem2(m - n, n)
}
What value is returned from the calls
c. Problem2(x, y),
where x and y are positive integers,
returns the greatest common divisor of x and y
Top Related