Download presentation
Presentation is loading. Please wait.
1
Recursion Chapter 12
2
12.1 Nature of Recursion Problems that lend themselves to a recursive solution have the following characteristics: One or more simple case of the problem have a straightforward, non-recursive solution Otherwise, use reduced cases of the problem that are closer to a stopping case Eventually the problem can be reduced to stopping cases only. Easy to solve
3
Nature of Recursion Splitting a problem into smaller problems Size n
4
Power by Multiplication
Raise 6 to the power of 3 Raise 6 to the power of 22 Multiply the result by 6 Raise 6 to the power of 2 Raise 6 to the power of 1 Multiplying 6 * 6 * 6
5
Power.cpp // FILE: Power.cpp // RECURSIVE POWER FUNCTION
// Raises its first argument to the power // indicated by its second argument. // Pre: m and n are defined and > 0. // Post: Returns m raised to power n. int power (int m, int n) { if (n <= 1) return m; else return m + power (m, n - 1); }
6
12.2 Tracing Recursive Functions
Hand tracing we see how algorithm works Very useful in recursion Previous Multiply example trace “Activation Frame” corresponds to a function call Darker shading shows the depth of recursion
7
Trace of Power
8
Recursive Function with No Return Value
If statement with some stopping condition n <= 1; When TRUE stopping case is reached recursive step is finished falls back to previous calls (if any) trace of reverse ReverseTest.cpp
9
ReverseTest.cpp #include <iostream> using namespace std;
void reverse(); int main () { reverse(); cout << endl; return 0; }
10
ReverseTest.cpp void reverse() { char next;
cout << "Next character or * to stop: "; cin >> next; if (next != ‘*’) reverse(); cout << next; }
11
Reverse Trace
12
Argument and Local Variable Stacks
How does C++ keep track of n and next ? Uses a data structure called a stack Think of a stack of trays in a cafeteria Each time a function is called it is pushed onto the stack Only top values are used when needed (popping) Example of calls to reverse
13
Recursive String After 1st call to reverse n next 3 ? top
c is read into next just prior to 2nd call 3 c top
14
Recursive String After 2nd call to reverse n next 2 ? top 3 c
letter a is read into next just prior to 3rd call 2 a top
15
Recursive String After 3rd call to reverse n next 1 ? top 2 a 3 c
letter t is read into next printed due to stop case 1 t top
16
Recursive String After 1st return After 2nd return
n next 2 a top 3 c After 2nd return After 3rd return (final) ? ?
17
12.3 Recursive Mathematical Functions
Many mathematical functions are defined recursively factorial n! of a number 0! = 1 n! = n * *n-1)! for n > 0 So 4! = 4 * 3 * 2 * 1 or 24 Look at a block of recursive math function example source code files
18
Factorial.cpp // FILE: Factorial.cpp // RECURSIVE FACTORIAL FUNCTION
// COMPUTES N! int factorial (int n) { if (n <= 0) return 1; else return n * factorial (n-1); }
19
Factorial Trace
20
FactorialI.cpp // FILE: FactorialI.cpp // ITERATIVE FACTORIAL FUNCTION
// COMPUTES N! int factorialI (int n) { int factorial; factorial = 1; for (int i = 2; i <= n; i++) factorial *= i; return factorial; }
21
Fibonacci.cpp // FILE: Fibonacci.cpp
// RECURSIVE FIBONACCI NUMBER FUNCTION int fibonacci (int n) // Pre: n is defined and n > 0. // Post: None // Returns: The nth Fibonacci number. { if (n <= 2) return 1; else return fibonacci (n - 2) + fibonacci (n - 1); }
22
GCDTest.cpp // FILE: gcdTest.cpp
// Program and recursive function to find // greatest common divisor #include <iostream> using namespace std; // Function prototype int gcd(int, int);
23
GCDTest.cpp int main() { int m, n; // the two input items
cout << "Enter two positive integers: "; cin >> m >> n; cout << endl; cout << "Their greatest common divisor is " << gcd(m, n) << endl; return 0; }
24
GCDTest.cpp // Finds the greatest common divisor of two // integers
// Pre: m and n are defined and both are > 0. // Post: None // Returns: The greatest common divisor of m and // n. int gcd(int m, int n) { if (m < n) return gcd(n, m);
25
GCDTest.cpp else if (m % n == 0) return n; else
return gcd(n, m % n); // recursive step }
26
GCDTest.cpp Program Output
Enter two positive integers separated by a space: 24 84 Their greatest common divisor is 12
27
12.4 Recursive Functions with Array Arguments
// File: findSumTest.cpp // Program and recursive function to sum an // array's elements #include <iostream> using namespace std; // Function prototype int findSum(int[], int); int binSearch(int[], int, int, int);
28
FindSumTest.cpp int main() { const int SIZE = 10; int x[SIZE];
int sum1; int sum2; // Fill array x for (int i = 0; i < SIZE; i++) x[i] = i + 1;
29
FindSumTest.cpp // Calulate sum two ways sum1 = findSum(x, SIZE);
sum2 = (SIZE * (SIZE + 1)) / 2; cout << "Recursive sum is " << sum1 << endl; cout << "Calculated sum is " << sum2 << endl; cout << binSearch(x, 10, 10, SIZE-1) << endl; return 0; }
30
FindSumTest.cpp // Finds the sum of integers in an n-element // array
int findSum(int x[], int n) { if (n == 1) return x[0]; else return x[n-1] + findSum(x, n-1); }
31
FindSumTest.cpp // Searches for target in elements first through
// last of array // Precondition : The elements of table are // sorted & first and last are defined. // Postcondition: If target is in the array, // return its position; otherwise, returns -1. int binSearch (int table[], int target, int first, int last) { int middle;
32
FindSumTest.cpp middle = (first + last) / 2; if (first > last)
return -1; else if (target == table[middle]) return middle; else if (target < table[middle]) return binSearch(table, target, first, middle-1); else return binSearch(table, target, middle+1, last); }
33
12.5 Problem Solving with Recursion
Case Study: The Towers of Hanoi Problem Statement Solve the Towers of Hanoi problem for n disks, where n is the number of disks to be moved from tower A to tower c Problem Analysis Solution is a printed list of each disk move. Recursive function that can be used to move any number of disks from one tower to the other tower.
34
Towers of Hanoi Program Design If n is 1 else
move disk 1 from fromTower to toTower else move n-1 disks from fromTower to aux tower using the toTower move disk n from the fromTower to the toTower move n-1 disks from aux tower to the toTower using fromTower
35
Towers of Hanoi Program Implementation Program Verification & Test
Towers.cpp Program Verification & Test towers (‘A’, ’C’, ‘B’, 3); Towers trace
36
Tower.cpp // File: tower.cpp // Recursive tower of hanoi function
#include <iostream> using namespace std; void tower(char, char, char, int); int main() { int numDisks; // input - number of disks
37
Tower.cpp cout << "How many disks: "; cin >> numDisks;
tower('A', 'C', 'B', numDisks); return 0; } // Recursive function to "move" n disks from // fromTower to toTower using auxTower // Pre: The fromTower, toTower, auxTower, and // n are defined. // Post: Displays the required moves.
38
Tower.cpp void tower (char fromTower, char toTower,
char auxTower, int n) { if (n == 1) cout << "Move disk 1 from tower " << fromTower << " to tower " << toTower << endl; else
39
Tower.cpp tower(fromTower, auxTower, toTower, n-1);
cout << "Move disk " << n << " from tower "<< fromTower << " to tower " << toTower << endl; tower(auxTower, toTower, fromTower, n-1); } } // end tower
40
Towers Trace
41
TowerTest.cpp Program Output Move disk 1 from tower A to tower C
Move disk 2 from tower A to tower B Move disk 1 from tower C to tower B Move disk 3 from tower A to tower C Move disk 1 from tower B to tower A Move disk 2 from tower B to tower C
42
12.6 Common Programming Errors
Stopping conditions Missing return statements Optimizations recursion of arrays use large amounts of memory use care when tracing your solutions
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.