|
1
|
|
|
2
|
|
|
3
|
- 14.1 Recursive Functions for
Tasks
- 14.2 Recursive Functions for
Values
- 14.3 Thinking Recursively
|
|
4
|
- When a function is defined in terms of itself
- A recursive function is a function that calls itself
- void foo(int n) {
- return foo(n-1);
- }
|
|
5
|
- To know what is a recursive function and the benefits of using recursive
- To determine the base cases in a recursive function
- To understand how recursive function calls are handled in a call stack
- To solve problems using recursion
- To use an overloaded helper function to derive a recursive function
- To understand the relationship and difference between recursion and iteration
|
|
6
|
- factorial(0) = 1;
- factorial(n) = n*factorial(n-1);
- /////////////////////////////////// Definition
/////////////////////////////////
- int factorial(int n) {
- if (n == 0) { // Base Case
- return 1;
- } else {
- return n * factorial(n - 1); // Recursive call
- }
- }
|
|
7
|
|
|
8
|
- factorial(3) = 3 * factorial(2)
|
|
9
|
- factorial(3) = 3 * factorial(2)
- = 3 * (2 *
factorial(1))
|
|
10
|
- factorial(3) = 3 * factorial(2)
- = 3 * (2 *
factorial(1))
- = 3 * ( 2 * (1
* factorial(0)))
|
|
11
|
- factorial(3) = 3 * factorial(2)
- = 3 * (2 *
factorial(1))
- = 3 * ( 2 * (1
* factorial(0)))
- = 3 * ( 2 * ( 1
* 1)))
|
|
12
|
- factorial(3) = 3 * factorial(2)
- = 3 * (2 *
factorial(1))
- = 3 * ( 2 * (1
* factorial(0)))
- = 3 * ( 2 * ( 1
* 1)))
- = 3 * ( 2 * 1)
|
|
13
|
- factorial(3) = 3 * factorial(2)
- = 3 * (2 *
factorial(1))
- = 3 * ( 2 * (1
* factorial(0)))
- = 3 * ( 2 * ( 1
* 1)))
- = 3 * ( 2 * 1)
- = 3 * 2
|
|
14
|
- factorial(3) = 3 * factorial(2)
- = 3 * (2 *
factorial(1))
- = 3 * ( 2 * (1
* factorial(0)))
- = 3 * ( 2 * ( 1
* 1)))
- = 3 * ( 2 * 1)
- = 3 * 2
- = 6
|
|
15
|
|
|
16
|
|
|
17
|
|
|
18
|
|
|
19
|
|
|
20
|
|
|
21
|
|
|
22
|
|
|
23
|
|
|
24
|
|
|
25
|
|
|
26
|
|
|
27
|
- Finonacci series: 0 1 1 2 3 5 8 13 21 34 55 89…
- indices: 0 1 2 3 4 5 6
7 8 9
10 11
- fib(0) = 0;
- fib(1) = 1;
- fib(index) = fib(index -1) + fib(index -2); assume index >=2
|
|
28
|
|
|
29
|
- All recursive methods have the following characteristics:
- One or more base cases (the simplest case) are used to stop recursion.
We know how to solve this case.
- Every recursive call reduces the original problem, bringing it
increasingly closer to a base case until it becomes that case.
- In general, to solve a problem using recursion, you break it into
subproblems. If a subproblem resembles the original problem, you can
apply the same approach to solve the subproblem recursively. This
subproblem is almost the same as the original problem in nature with a
smaller size.
|
|
30
|
- Let us consider a simple problem of printing a message for n times. You
can break the problem into two subproblems:
- print the message one time
- print the message for n-1 times.
The second problem is the same as the original problem with a
smaller size. The base case for the problem is n==0.
|
|
31
|
- void printMsg(char *aMessage, int aTimes) {
- if(aTimes >= 1) {
- cout << aMessage << aTimes << endl;
- printMsg(aMessage, aTimes-1);
- }
- }
|
|
32
|
- Many of the problems presented in the early chapters can be solved using
recursion if you think recursively.
For example, the palindrome problem can be solved recursively as
follows:
|
|
33
|
- Find the largest number in the list and swaps it with the last number.
- Ignore the last number and sort the remaining ints in the list recursively.
|
|
34
|
- There are n disks labeled 1, 2, 3, . . ., n, and three towers labeled A,
B, and C.
- No disk can be on top of a smaller disk at any time.
- All the disks are initially placed on tower A.
- Only one disk can be moved at a time, and it must be the top disk on the
tower.
|
|
35
|
|
|
36
|
- The Towers of Hanoi problem can be decomposed into three subproblems.
|
|
37
|
- Move the first n - 1 disks from A to C with the assistance of tower B.
- Move disk n from A to B.
- Move n - 1 disks from C to B with the assistance of tower A.
|