Lecture13

Lecture13 - 5/12/10 CMPSC 24: Lecture 13 Recursion...

Info iconThis preview shows page 1. Sign up to view the full content.

View Full Document Right Arrow Icon
This is the end of the preview. Sign up to access the rest of the document.

Unformatted text preview: 5/12/10 CMPSC 24: Lecture 13 Recursion Divyakant Agrawal Department of Computer Science UC Santa Barbara 5/12/10 1 Lecture Plan •  Recursion –  General structure of recursive soluIons –  Why do recursive soluIons terminate? –  How do recursive programs manage the stack? –  Tail recursion –  When to use recursion? 2 What Is Recursion? Recursion like a set of Russian dolls. 3 1 5/12/10 What Is Recursion? •  Recursive call A method call in which the method being called is the same as the one making the call •  Direct recursion Recursion in which a method directly calls itself –  example •  Indirect recursion Recursion in which a chain of two or more method calls returns to the method that originated the chain –  example 4 Recursion •  You must be careful when using recursion. •  Recursive soluIons can be less efficient than iteraIve soluIons. •  SIll, many problems lend themselves to simple, elegant, recursive soluIons. 5 Some DefiniIons •  Base case The case for which the soluIon can be stated non‐recursively •  General (recursive) case The case for which the soluIon is expressed in terms of a smaller version of itself •  Recursive algorithm A soluIon that is expressed in terms of (a) smaller instances of itself and (b) a base case 6 2 5/12/10 Finding a Recursive SoluIon •  Each successive recursive call should bring you closer to a situaIon in which the answer is known. •  A case for which the answer is known (and can be expressed without recursion) is called a base case. •  Each recursive algorithm must have at least one base case, as well as the general (recursive) case 7 General format for many recursive funcIons if (some condiIon for which answer is known) // base case soluIon statement else // general case recursive funcIon call 8 CompuIng Factorial Recursive defini:on A definiIon in which something is defined in terms of a smaller version of itself What is 3 factorial? 9 3 5/12/10 CompuIng Factorial 10 Recursive ComputaIon 11 Factorial Program The func:on call Factorial(4) should have value 24, because that is 4 * 3 * 2 * 1 . For a situa:on in which the answer is known, the value of 0! is 1. So our base case could be along the lines of if ( number == 0 ) return 1; 12 4 5/12/10 Factorial Program Now for the general case . . . The value of Factorial(n) can be wriNen as n * the product of the numbers from (n ‐ 1) to 1, that is, n * (n ‐ 1) * . . . * 1 or, n * Factorial(n ‐ 1) And no:ce that the recursive call Factorial(n ‐ 1) gets us “closer” to the base case of Factorial(0). 13 Recursive Factorial int Factorial ( int number ) // Pre: number >= 0. { if ( number == 0) // base case return 1 ; else // general case return number * Factorial ( number - 1 ) ; } Why is this correct? 14 Three‐QuesIons for Verifying Recursive FuncIons •  Base‐Case Ques:on: Is there a non‐recursive way out of the func:on? •  Smaller‐Caller Ques:on: Does each recursive func:on call involve a smaller case of the original problem leading to the base case? •  General‐Case Ques:on: Assuming each recursive callworks correctly, does the whole func:on work correctly? 15 5 5/12/10 CompuIng ExponenIaIon Recursively •  From mathema:cs, we know that 20 = 1 and 25 = 2 * 24 •  In general, x0 = 1 and xn = x * xn‐1 for integer x, and integer n > 0. •  Here we are defining xn recursively, in terms of xn‐1 16 // Recursive definition of power function int Power ( int x, int n) { if ( n == 0 ) return 1; // base case else // general case return ( x * Power ( x , n-1 ) ) ; } Can you compute mulIplicaIon recursively? How about addiIon? 17 Fibonacci Sequence 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? 18 6 5/12/10 Fibonacci Program int Fibonacci(int n) { if (n == 0 || n == 1) return n; else return Fibonacci(n-2) + Fibonacci(n-1); ) That was easy, but it is not very efficient. Why? 19 Recursive Linear Search struct ListType { int length ; // number of elements in the list int info[ MAX_ITEMS ] ; }; ListType list ; 20 Problem Instance PROTOTYPE bool ValueInList( ListType list , int value , int startIndex ) ; 74 36 . . . 95 list[0] [1] [startIndex] 75 29 47 . . . [length ‐1] index Already searched of Needs to be searched current element to examine 21 7 5/12/10 bool ValueInList ( ListType list , int value, int startIndex ) // Searches list for value between positions startIndex // and list.length-1 // Pre: list.info[ startIndex ] . . list.info[ list.length - 1 ] // contain values to be searched // Post: Function value = // ( value exists in list.info[ startIndex ] . . // list.info[ list.length - 1 ] ) { if ( list.info[startIndex] == value ) // one base case return true ; else if (startIndex == list.length -1 ) // another base case return false ; else // general case return ValueInList( list, value, startIndex + 1 ) ; } 22 22 “Why Use Recursion?” • Those examples could have been wrihen without recursion, using iteraIon instead. The iteraIve soluIon uses a loop, and the recursive soluIon uses an if statement. • However, for certain problems the recursive soluIon is the most natural soluIon. Build a prototype. A more efficient iteraIve soluIon can be developed later. • Recursive soluIons are easier to reason about. • The FuncDonal Programming paradigm adopts recursion. 23 Printing List in Reverse struct NodeType { int info ; NodeType* next ; } class SortedType { public : . . . private : NodeType* listData ; }; 24 8 5/12/10 RevPrint(listData) listData A B C D E FIRST, print out this secIon of list, backwards THEN, print this element 25 Base Case and General Case Base case: list is empty Do nothing General case: list is non‐empty Extract the first element; Print rest of the list (may be empty); Print the first element 26 PrinIng in Reverse void RevPrint ( NodeType* listPtr ) { if { ( listPtr != NULL ) // general case RevPrint ( listPtr-> next ) ; //process the rest std::cout << listPtr->info << std::endl ; // print this element } // Base case : if the list is empty, do nothing } How would this work without recursion? 27 9 5/12/10 FuncIon BinarySearch( )   BinarySearch takes sorted array info, and two subscripts, fromLoc and toLoc, and item as arguments. It returns false if item is not found in the elements info[fromLoc…toLoc]. Otherwise, it returns true.   BinarySearch can be wrihen using iteraIon, or using recursion. 28 FuncIon BinarySearch( ) bool BinarySearch( ItemType info[ ], ItemType item, int fromLoc , int toLoc ) // Pre: info [ fromLoc . . toLoc ] sorted in ascending order // Post: Function value = ( item in info [ fromLoc .. toLoc] ) { int if mid; ( fromLoc > toLoc ) // base case -- not found return false ; else { mid = ( fromLoc + toLoc ) / 2 ; switch ( item.ComparedTo( info [ mid ] ) ) { case EQUAL: return true; //base case-- found at mid case LESS: return BinarySearch ( info, item, fromLoc, mid-1 ); case GREATER: return BinarySearch( info, item, mid + 1, toLoc ); } } Which version is easier: compare to iteraIve version presented next 29 IteraIve BinarySearch( ) bool BinarySearch( ItemType info, ItemType item, { int mid ; int first = fromLoc; int last = toLoc; bool found = false ; while (( first <= last ) && !found ) { mid = ( first + last ) / 2 ; switch ( item.ComparedTo( info [ mid ] ) ) { case LESS: last = mid - 1 ; break ; case GREATER: first = mid + 1 ; break ; case EQUAL: found = true ; break ; } } return found; } int fromLoc, int toLoc) 30 10 5/12/10 When a funcIon is called... •  A transfer of control occurs from the calling block to the code of the func:on. It is necessary that there be a return to the correct place in the calling block ader the func:on code is executed. This correct place is called the return address. •  When any func:on is called, the run‐:me stack is used. On this stack is placed an ac:va:on record (stack frame) for the func:on call. –  This stores all the variables local to the called func:on. 31 Stack AcIvaIon Frames •  The ac:va:on record stores the return address for this func:on call, and also the parameters, local variables, and the func:on’s return value. •  The ac:va:on record for a par:cular func:on call is popped off the run‐:me stack when the final closing brace in the func:on code is reached, or when a return statement is reached in the func:on code. •  At this :me the func:on’s return value, if non‐void, is brought back to the calling block return address for use there. 32 Mystery Recursive FuncIon // Another recursive function int Func ( int a, int b ) { int result; if ( b == 0 ) result = 0; else if ( b > 0 ) result = a + // // Func ( a , b - 1 ) ) ; base case first general case // instruction 50 else // second general case result = Func ( - a , - b ) ; // instruction 70 return result; } 33 11 5/12/10 Run‐Time Stack AcIvaIon Records Run‐Time Stack AcIvaIon Records // original call is instrucIon 100 x = Func(5, 2); FCTVAL ? result ? b 2 a 5 Return Address 100 original call at instrucIon 100 pushes this record for Func(5,2) 34 Second Call x = Func(5, 2); // original call at instrucIon 100 FCTVAL ? result ? b 1 a 5 Return Address 50 FCTVAL ? result 5+Func(5,1) = ? b 2 a 5 Return Address 100 call in Func(5,2) code at instrucIon 50 pushes on this record for Func(5,1) record for Func(5,2) 35 Run‐Time Stack AcIvaIon Records Third Call x = Func(5, 2); FCTVAL ? result ? b 0 a 5 Return Address 50 FCTVAL ? result 5+Func(5,0) = ? b 1 a 5 Return Address 50 FCTVAL ? result 5+Func(5,1) = ? b 2 a 5 Return Address 100 // original call at instrucIon 100 call in Func(5,1) code at instrucIon 50 pushes this record for Func(5,0) record for Func(5,1) record for Func(5,2) 36 12 5/12/10 Run‐Time Stack AcIvaIon Records Third Call Completes x = Func(5, 2); FCTVAL 0 result 0 b 0 a 5 Return Address 50 FCTVAL ? result 5+Func(5,0) = ? b 1 a 5 Return Address 50 FCTVAL ? result 5+Func(5,1) = ? b 2 a 5 Return Address 100 // original call at instrucIon 100 record for Func(5,0) is popped first with its FCTVAL record for Func(5,1) record for Func(5,2) 37 Run‐Time Stack AcIvaIon Records Second Call Completes x = Func(5, 2); FCTVAL 5 result 5+Func(5,0) = 5+ 0 b 1 a 5 Return Address 50 FCTVAL ? result 5+Func(5,1) = ? b 2 a 5 Return Address 100 // original call at instrucIon 100 record for Func(5,1) is popped next with its FCTVAL record for Func(5,2) 38 Run‐Time Stack AcIvaIon Records First Call Completes x = Func(5, 2); // original call at line 100 FCTVAL 10 result 5+Func(5,1) = 5+5 b 2 a 5 Return Address 100 record for Func(5,2) is popped last with its FCTVAL 39 13 5/12/10 PracIce: Show AcIvaIon Records For These Calls x = Func( ‐ 5, ‐ 3 ); x = Func( 5, ‐ 3 ); What opera:on does Func(a, b) simulate? 40 Tail Recursion •  The case in which a func:on contains only a single recursive call and it is the last statement to be executed in the func:on. •  Tail recursion can be replaced by itera:on to remove recursion from the solu:on as in the next example. 41 Tail Recursion Example bool ValueInList ( ListType list , int value , int startIndex ) { if ( list.info[startIndex] == value ) // one base case return true ; else if (startIndex == list.length -1 ) // another base case return false ; else // general case return ValueInList( list, value, startIndex + 1 ) ; } 42 14 5/12/10 Equivalent IteraIve Version bool ValueInList ( ListType list , int value , int startIndex { while (list.info[startIndex] != value && startIndex != list.length-1 ) startIndex++ ; if ( value == list.info[ startIndex ] ) return true ; else return false; } ) So, what is the general logic? 43 Convert into IteraIve SoluIon int Power(int number, int exponent) { if (exponent == 0) return 1 else return number * Power(number, exponent - 1) } 44 IteraIve Equivalent int Power (int number, int exponent) { int val = 1; while (exponent != 0) { val = number*val; What is the logic? exponent‐‐; } return val; } 45 15 5/12/10 Tower of Hanoi Worked out on the blackboard 46 16 ...
View Full Document

This note was uploaded on 12/27/2011 for the course CMPSC 24 taught by Professor Agrawal during the Fall '09 term at UCSB.

Ask a homework question - tutors are online