1 / 42

Recursion

Recursion. Chapter 12. 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

johannes
Download Presentation

Recursion

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  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 Problem Size n-1 Problem Size n-2 Problem Size 1 problem Size 1 problem Size 1 problem

  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 • Multiply the result by 6 • 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 n next 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 n next 2 a top 3 c

  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 n next 1 t top 2 a 3 c

  16. Recursive String • After 1st return n next 2 a top 3 c • After 2nd return n next 3 c • 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 • 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 • 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 Move disk 1 from tower A 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

More Related