Chapter 7 Programming with Recursion Fall 2017 Yanjun Li CS2200 1 What Is Recursion? How is recursion like a set of Russian dolls? Fall 2017 Yanjun Li CS2200 2
What Is Recursion? Recursive call A method call in which the method being called is the same as the one making the call A recursive function is a function that invokes itself directly or indirectly. Fall 2017 Yanjun Li CS2200 3 Example of Recursion Recursive definition A definition in which something is defined in terms of a smaller version of itself What is 3 factorial? Fall 2017 Yanjun Li CS2200 4
Example of Recursion Fall 2017 Yanjun Li CS2200 5 Examples of Recursion Fall 2017 Yanjun Li CS2200 6
Recursive Algorithm Base case The case for which the solution can be stated nonrecursively The case to stop recursion. General (recursive) case The case for which the solution is expressed in terms of a smaller version of itself Recursive algorithm A solution that is expressed in terms of (a) a smaller instance(s) of itself and (b) a base case(s) Fall 2017 Yanjun Li CS2200 7 Factorial Problem Base case : 0! = 1; General (recursive) case : n!= n* (n-1)!; Recursive algorithm //pre: n >=0 int factorial(int n) //n! if (n == 0) //base case return 1; else //recursive case return n * factorial(n-1); Fall 2017 Yanjun Li CS2200 8
Writing Recursive Solutions Algorithm for writing recursive solutions Determine the size of the problem Size is the factor that is getting smaller Size is usually a parameter to the problem Identify the base case(s) The case(s) for which you know the answer Identify the general case(s) The case(s) that can be expressed as a smaller version of the size Fall 2017 Yanjun Li CS2200 9 Writing Recursive Solutions Let s try it Problem: Calculate X n (X to the nth power) What is the size of the problem? Which case do you know the answer to? Which case can you express as a smaller version of the size? Recursive formulation: X n =X*(X n-1 ) Fall 2017 Yanjun Li CS2200 10
Writing Recursive Solutions int Power(int number, int exponent) if (exponent == 0) //base case return 1; else //recursive case return number * Power(number, exponent - 1); Do we need a precondition? Fall 2017 Yanjun Li CS2200 11 Writing Recursive Solutions Pattern of solution if (some condition for which answer is known) solution statement else function call Fall 2017 Yanjun Li CS2200 12
Writing Recursive Solutions Shall we try it again? Problem: Calculate Nth item in Fibonacci sequence 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55 What is the next number? What is the size of the problem? Which case do you know the answer to? Which case can you express as a smaller version of the size? Fall 2017 Yanjun Li CS2200 13 Writing Recursive Solutions //pre: n>=0 int Fibonacci(int n) if (n == 0 n == 1) return n; else return Fibonacci(n-2) + Fibonacci(n-1); ) Fall 2017 Yanjun Li CS2200 14
Verifying Recursive Solutions How can we prove that the solution works? Base-Case Question: Is there a non-recursive way out of the function? Smaller-Caller Question: Does each recursive function call involve a smaller case of the original problem leading to the base case? General-Case Question: Assuming each recursive call works correctly, does the whole function work correctly? Can you answer yes to all three questions? Fall 2017 Yanjun Li CS2200 15 Verifying Recursive Solutions int Power(int number, int exponent) if (exponent == 0) return 1; else return number * Power(number, exponent - 1); Is there a non-recursive way out? Does each call involve a small case of original? Assuming recursive call works, does the entire function work? Fall 2017 Yanjun Li CS2200 16
Writing Recursive Solutions Shall we try it again? Problem: Search a list of integers for a value and return true if it is in the list and false otherwise What is the size of the problem? Fall 2017 Yanjun Li CS2200 17 Writing Recursive Solutions bool ValueInList(ListType data, int value, int startindex); Which case do you know the answer to? Which case can you express as a smaller version of the size? Fall 2017 Yanjun Li CS2200 18
Writing Recursive Solutions bool ValueInList(ListType list, int value, int startindex) if (list.info[startindex] == value) return true; Base Case 1 else if (startindex == list.length -1) return false; Base Case 2 else return ValueInList(list, value, startindex + 1); Fall 2017 Yanjun Li CS2200 19 Writing Recursive Solutions Why use recursion? True, these examples could more easily be solved using iteration. However, a recursive solution is a natural solution in certain cases, especially when pointers are involved. Fall 2017 Yanjun Li CS2200 20
Writing Recursive Solutions Printing a list in order Size? Base case? Recursive (general) case? Fall 2017 Yanjun Li CS2200 21 Writing Recursive Solutions struct NodeType int info; NodeType * next; ; void Print(NodeType* listptr) if (listptr!= NULL) cout << listptr->info << endl; Print(listPrt->next); Where is the base case? Fall 2017 Yanjun Li CS2200 22
Writing Recursive Solutions Printing a list in reverse order What must be changed from the in-order print to make the code print in reverse order? Fall 2017 Yanjun Li CS2200 23 Writing Recursive Solutions void RevPrint(NodeType* listptr) if (listptr!= NULL) RevPrint(listPrt->next); cout << listptr->info << endl; Fall 2017 Yanjun Li CS2200 24
Writing Recursive Solutions Can you verify the RevPrint algorithm using the three-question method? Base-Case question? Smaller-Caller Question? General-Case Question? Fall 2017 Yanjun Li CS2200 25 Binary Search binarysearch (an anarray of ArrayType, a value of ItemType): if (anarray is of size 1) Determine if anarray s item is equal to value else Find the midpoint of anarray Determine which half of anarray contains value if (value is in the first half of anarray) binarysearch(first half of anarray, value) else binarysearch(second half of anarray, value) Fall 2017 Yanjun Li CS2200 26
Binary Search Implementation issues: How will you pass half of anarray to the recursive calls to binarysearch? How do you determine which half of the array contains value? What should the base case(s) be? How will binarysearch indicate the result of the search? Fall 2017 Yanjun Li CS2200 27 int Mystery( ItemType info[ ], ItemType item, int fromloc, int toloc ) int mid; if ( fromloc > toloc ) return -1; //base case else mid = ( fromloc + toloc ) / 2 ; if (info[mid] == item) return mid; else if (item < info[mid]) return Mystery (info,item,fromloc,mid-1 ); else return Mystery(info,item,mid + 1,toLoc) ; What does this function return? Fall 2017 Yanjun Li CS2200 28
Mr. Spock s Dilemma (Choosing r out of n Things) Problem How many different choices are possible for exploring r planets out of n planets in a solar system? A combination problem Fall 2017 Yanjun Li CS2200 29 Mr. Spock s Dilemma (Choosing r out of n Things) Let c(n, r) be the number of groups of r planets chosen from n In terms of Planet X: c(n, r) = the number of groups of r planets that include Planet X + the number of groups of r planets that do not include Planet X Fall 2017 Yanjun Li CS2200 30
Mr. Spock s Dilemma (Choosing r out of n Things) The number of ways to choose r out of n things is the sum of The number of groups of r planets that include Planet X The number of ways to choose r 1 out of n 1 things since X is chosen already c(n 1, r 1) And the number of groups of r planets that do not include Planet X The number of ways to choose r out of n 1 things c(n 1, r) c(n, r) = c(n 1, r 1) + c(n 1, r) Fall 2017 Yanjun Li CS2200 31 Mr. Spock s Dilemma (Choosing r out of n Things) Base cases There is one group of everything c(r, r) = 1 There is one group of nothing c(n, 0) = 1 Although r cannot exceed n here, we want our solution to be general c(n, r) = 0 if r > n Fall 2017 Yanjun Li CS2200 32
Mr. Spock s Dilemma (Choosing r out of n Things) Recursive solution c(n, k) = 1 if r = 0 1 if r = n 0 if r > n c(n 1, r 1) + c(n 1, r) if 0 < r < n Fall 2017 Yanjun Li CS2200 33 Mr. Spock s Dilemma (Choosing r out of n Things) Figure 2-12 The recursive calls that c(4, 2) generates Fall 2017 Yanjun Li CS2200 34
Organizing Data: The Towers of Hanoi The goal is to move all the discs from the left peg to the right one. Only one disc may be moved at a time. A disc can be placed either on an empty peg or on top of a larger disc. Try to use the smallest number of moves possible. http://www.dynamicdrive.com/dynamicindex12/towerhanoi.htm Fall 2017 Yanjun Li CS2200 35 Organizing Data: The Towers of Hanoi Figure 2-19a and b (a) The initial state; (b) move n - 1 disks from A to C Fall 2017 Yanjun Li CS2200 36
The Towers of Hanoi Figure 2-19c and d (c) move one disk from A to B; (d) move n - 1 disks from C to B Fall 2017 Yanjun Li CS2200 37 The Towers of Hanoi solvetowers( n, source, destination, spare) //move n from A to C if (n is 1) Move a disk directly from source to destination //move 1 from A to C else solvetowers(n-1, source, spare, destination) //move n-1 from A to B solvetowers(1, source, destination, spare) //move 1 from A to C solvetowers(n-1, spare, destination, source) //move n-1 from B to C //end if Fall 2017 Yanjun Li CS2200 38
The Towers of Hanoi If T N is the minimum number of moves needed to solve the puzzle with N disks: T 0 = 0 //base case T N <=T N-1 +1+T N-1 = 2T N-1 +1 when N>0 Move the top N-1 disks from A to B (using C as a spare peg) // T N-1 Move the bottom disk from A to C // 1 Move N-1 disks from B to C (using A as a spare peg) // T N-1 Fall 2017 Yanjun Li CS2200 39 Recursion and Efficiency Some recursive solutions are so inefficient that they should not be used Factors that contribute to the inefficiency of some recursive solutions Overhead associated with function calls Inherent inefficiency of some recursive algorithms (combination problem) Fall 2017 Yanjun Li CS2200 40
Recursion and Efficiency Do not use a recursive solution if it is inefficient and there is a clear, efficient iterative solution Fall 2017 Yanjun Li CS2200 41 When To Use Recursion Depth of recursive calls is relatively shallow compared to the size of the problem Recursive version does about the same amount of work as the non-recursive version (same Big-O) The recursive version is shorter and simpler than the non-recursive solution SHALLOW DEPTH EFFICIENCY CLARITY Fall 2017 Yanjun Li CS2200 42
Reference Reproduced from C++ Plus Data Structures, 4 th edition by Nell Dale. Reproduced by permission of Jones and Bartlett Publishers International. Fall 2017 Yanjun Li CS2200 43