Upcoming SlideShare
×

# Lecture09 recursion

389 views
309 views

Published on

1 Like
Statistics
Notes
• Full Name
Comment goes here.

Are you sure you want to Yes No
Your message goes here
• Be the first to comment

Views
Total views
389
On SlideShare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
13
0
Likes
1
Embeds 0
No embeds

No notes for slide

### Lecture09 recursion

1. 1. Chapter 9Recursion 1
2. 2. Recursive Functions• Recursive functions are functions that call themselves.• Data structures, especially linked implementations of binary trees, sometimes use recursive functions. 2
3. 3. Example: Factorial Function• The factorial function is often written as a recursive function.• The factorial of a positive integer is the product of all positive integers less than or equal to the number. 5 factorial is written 5! 5! = 5 * 4 * 3 * 2 * 1 = 120 3! = 3 * 2 * 1 = 6 0! is defined to be 1 3
4. 4. Factorial Function1 int factorial( int num )2 {3 if ( num == 0 || num == 1 )4 return 1;5 return num * factorial( num – 1 );6 } The recursive function call 4
5. 5. What Happens When a Function Calls Itself?• When a function calls itself, it is not actually executing itself again.• Instead, another function is made which is identical.• Then, that function is called from the recursive function call.• This will be illustrated in the slides that follow… 5
6. 6. Recursive Processx = factorial( 4 ); A function call that should produce 24 as a result and assign it to x. 6
7. 7. Recursive Process (cont.)x = factorial( 4 ); 4 is passed into numint factorial( int num ){ 4 4 4 replaces eachif ( num == 0 || num == 1 ) occurrence of num return 1;return num * factorial( num – 1 );} 4 4 7
8. 8. Recursive Process (cont.)x = factorial( 4 ); A recursive function callint factorial( int num ) is made – an identical{ 4 4 factorial function is madeif ( num == 0 || num == 1 ) and called. return 1;return num * factorial( 3 );} 4 8
9. 9. Recursive Processx = factorial( 4 ); (cont.)int factorial( int num ){ 4 4if ( num == 0 || num == 1 ) return 1;return num * factorial( 3 );} 4 3 is passed into numint factorial( int num ) 3 replaces each{ 3 3 occurrence of numif ( num == 0 || num == 1 ) return 1;return num * factorial( num – 1 );} 3 3 9
10. 10. Recursive Processx = factorial( 4 ); (cont.)int factorial( int num ){ 4 4if ( num == 0 || num == 1 ) return 1;return num * factorial( 3 );} 4int factorial( int num ) A recursive function{ 3 call is made – an 3if ( num == 0 || num == 1 ) identical factorial return 1; function is madereturn num * factorial( 2 ); and called.} 3 10
11. 11. Recursive Processx = factorial( 4 ); (cont.)int factorial( int num ) int factorial( int num ){ 4 4 { 2if ( num == 0 || num == 1 ) 2 return 1; if ( num == 0 || num == 1 )return num * factorial( 3 ); return 1;} 4 return num * factorial( num – 1 ); } 2 2int factorial( int num ){ 3 3if ( num == 0 || num == 1 ) 2 gets passed into num return 1;return num * factorial( 2 );} 3 2 replaces each occurrence of num 11
12. 12. Recursive Processx = factorial( 4 ); (cont.)int factorial( int num ) int factorial( int num ){ 4 4 { 2if ( num == 0 || num == 1 ) 2 return 1; if ( num == 0 || num == 1 )return num * factorial( 3 ); return 1;} return num * factorial( 1 ); 4 } 2int factorial( int num ){ 3 3 A recursive functionif ( num == 0 || num == 1 ) return 1; call is made – anreturn num * factorial( 2 ); identical factorial} 3 function is made and called. 12
13. 13. Recursive Processx = factorial( 4 ); (cont.) 1 is int factorial( int num )int factorial( int num ) { 2 2 passed{ 4 4if ( num == 0 || num == 1 ) if ( num == 0 || num == 1 ) into num return 1; return 1;return num * factorial( 3 ); return num * factorial( 1 ); }} 2 4int factorial( int num ) int factorial( int num ){ 3 3 { 1 1if ( num == 0 || num == 1 ) return 1; if ( num == 0 || num == 1 )return num * factorial( 2 ); return 1;} 3 return num * factorial( num – 1 ); } 1 1 13
14. 14. Recursive Processx = factorial( 4 ); (cont.) int factorial( int num )int factorial( int num ) { 2 2{ 4 4 if ( num == 0 || num == 1 )if ( num == 0 || num == 1 ) return 1; return 1;return num * factorial( 3 ); return num * factorial( 1 ); }} 2 4 int factorial( int num )int factorial( int num ) { 1 1{ 3 3 if ( num == 0 || num == 1 )if ( num == 0 || num == 1 ) return 1; return 1; return num * factorial( num – 1 );return num * factorial( 2 ); }} 1 1 3 Where is 1 returned? 14
15. 15. Recursive Processx = factorial( 4 ); (cont.) int factorial( int num )int factorial( int num ) { 2 2{ 4 4 if ( num == 0 || num == 1 )if ( num == 0 || num == 1 ) return 1; return 1;return num * factorial( 3 ); return num * factorial( 1 ); }} 2 4 int factorial( int num )int factorial( int num ) { 1 1{ 3 3 if ( num == 0 || num == 1 )if ( num == 0 || num == 1 ) return 1; return 1; return num * factorial( num – 1 );return num * factorial( 2 ); }} 1 1 3 The 1 replaces the function call that called this function (just as we would expect with any function call) 15
16. 16. Recursive Processx = factorial( 4 ); (cont.) int factorial( int num )int factorial( int num ) { 2 2{ 4 4 if ( num == 0 || num == 1 )if ( num == 0 || num == 1 ) return 1; return 1;return num * factorial( 3 ); return num * 1; }} 2 4 int factorial( int num )int factorial( int num ) { 1 1{ 3 3 if ( num == 0 || num == 1 )if ( num == 0 || num == 1 ) return 1; return 1; return num * factorial( num – 1 );return num * factorial( 2 );} } 1 1 3 The last function has finished 16
17. 17. Recursive Processx = factorial( 4 ); (cont.) int factorial( int num )int factorial( int num ) { 2 2{ 4 4 if ( num == 0 || num == 1 )if ( num == 0 || num == 1 ) return 1; return 1;return num * factorial( 3 ); return 2; }} 4int factorial( int num ) The execution of this{ 3 3 return statement can nowif ( num == 0 || num == 1 ) return 1; resumereturn num * factorial( 2 );} 3 17
18. 18. Recursive Processx = factorial( 4 ); (cont.) int factorial( int num )int factorial( int num ) { 2 2{ 4 4 if ( num == 0 || num == 1 )if ( num == 0 || num == 1 ) return 1; return 1;return num * factorial( 3 ); return 2; }} 4int factorial( int num ) It now returns 2 back{ 3 3 to the function callif ( num == 0 || num == 1 ) return 1; that called thisreturn num * factorial( 2 ); function.} 3 18
19. 19. Recursive Processx = factorial( 4 ); (cont.)int factorial( int num ){ 4 4if ( num == 0 || num == 1 ) return 1;return num * factorial( 3 );} 4int factorial( int num ){ 3 3if ( num == 0 || num == 1 ) return 1;return 6;} 19
20. 20. Recursive Processx = factorial( 4 ); (cont.)int factorial( int num ){ 4 4if ( num == 0 || num == 1 ) return 1;return num * 6;} 4int factorial( int num ){ 3 3if ( num == 0 || num == 1 ) return 1;return 6;} 20
21. 21. Recursive Process (cont.)x = factorial( 4 );int factorial( int num ){ 4 4if ( num == 0 || num == 1 ) return 1;return 24;} 21
22. 22. Recursive Process (cont.)x = 24; x gets the correct value of 24 22
23. 23. Base Case Notice that these1 int factorial( int num ) lines stopped the2 {3 if ( num == 0 || num == 1 ) recursion – without these lines, the4 return 1; function will call5 return num * factorial( num – 1 );6 } itself over and over again (infinite recursion) 23
24. 24. Base Case (cont.) These lines are1 int factorial( int num ) called the base2 {3 if ( num == 0 || num == 1 ) case – the case that stops the4 return 1; recursion.5 return num * factorial( num – 1 );6 } 24
25. 25. Recursive Case1 int factorial( int num )2 {3 if ( num == 0 || num == 1 )4 return 1;5 return num * factorial( num – 1 );6 } This line that produces a recursive function call is called the recursive case. All recursive functions have a base case and a recursive case (and sometimes more than one of each). 25
26. 26. What If?1 int factorial( int num )2 {3 if ( num == 0 || num == 1 )4 return 1;5 return num * factorial( num – 1 );6 } If one makes a mistake and inputs a negative number into this function: factorial( -2 ); what will happen? 26
27. 27. Infinite Recursion1 int factorial( int num )2 {3 if ( num == 0 || num == 1 )4 return 1;5 return num * factorial( num – 1 );6 } If one makes a mistake and inputs a negative number into this function: factorial( -2 ); what will happen? Infinite recursion. 27
28. 28. Drivers1 int factorial2( int num )2 {3 if ( num == 0 || num == 1 )4 return 1;5 return num * factorial2( num – 1 );6 } In order to prevent this problem, we can change the name of this function to factorial2… 28
29. 29. Drivers (cont.)1 int factorial2( int num )2 {3 if ( num == 0 || num == 1 )4 return 1;5 return num * factorial2( num – 1 );6 } and then write a factorial function, called a driver, to call this function… 29
30. 30. Drivers (cont.)int factorial( int num ){if ( num < 0 ) { cout << “The factorial of a negative number is undefined” << endl; return 0; }return factorial2( num );} 30
31. 31. Guidelines• There must be a base case that stops recursion.• Each recursive call should approach the base case.• The recursive function call should work for the base case.• The recursive function call should work for the case next to the base case.• The recursive function should make logical sense, assuming that the recursive function call inside it does everything it should do. 31
32. 32. Example• When you know the case next to the base case works, you know factorial( 2 ) works.• Since 3! = 3 * factorial( 2 ), you know factorial( 3 ) works – makes logical sense.• Since 4! = 4 * factorial( 3 ) and you know that factorial( 3 ) works, you know that factorial( 4 ) works.• Etc., etc. 32
33. 33. Recursion on a Linked List (cont.)bool search( Node<T> *ptr, T& foundItem, T& target){ if ( ptr == NULL ) return false; if ( ptr->info == target ) { foundItem = ptr->info; return true; } return search( ptr->next, foundItem, target );} Searching for a Mercedes in the linked list: Car mercedes, foundCar; … bool found = search( start, foundCar, mercedes ); 33
34. 34. Recursion on a Linked List (cont.)bool search( Node<T> *ptr, T& foundItem, T& target){ if ( ptr == NULL ) return false; Overloaded if ( ptr->info == target ) { operator in Car foundItem = ptr->info; struct return true; } return search( ptr->next, foundItem, target );} 34
35. 35. Recursion on a Linked List (cont.)bool search( Node<T> *ptr, T& foundItem, T& target){ if ( ptr == NULL ) return false; if ( ptr->info == target ) { foundItem = ptr->info; return true; } return search( ptr->next, foundItem, target );} Returns true if in list; returns false otherwise. 35
36. 36. Recursion on a Linked List (cont.)bool search( Node<T> *ptr, T& foundItem, T& target){ if ( ptr == NULL ) If true is returned, return false; foundItem will be if ( ptr->info == target ) { assigned Mercedes foundItem = ptr->info; (passed by reference return true; on each recursive } call) return search( ptr->next, foundItem, target );} 36
37. 37. Recursion on a Linked List (cont.)bool search( Node<T> *ptr, T& foundItem, T& target){ if ( ptr == NULL ) Two return false; base if ( ptr->info == target ) { cases foundItem = ptr->info; return true; } return search( ptr->next, foundItem, target );} 37
38. 38. Recursion on a Linked List (cont.)bool search( Node<T> *ptr, T& foundItem, T& target){ if ( ptr == NULL ) return false; if ( ptr->info == target ) { foundItem = ptr->info; return true; } return search( ptr->next, foundItem, target );} Don’t forget the return ( it is a common mistake)… 38
39. 39. Recursion on a Linked List (cont.)bool search( Node<T> *ptr, T& foundItem, T& target){ if ( ptr == NULL ) return false; if ( ptr->info == target ) { foundItem = ptr->info; return true; } return search( ptr->next, foundItem, target );} It passes the true/false value (from base cases) back through the succession of recursive function calls. 39
40. 40. Recursion on a Linked List (cont.)bool search( Node<T> *ptr, T& foundItem, T& target){ if ( ptr == NULL ) return false; if ( ptr->info == target ) { foundItem = ptr->info; return true; } return search( ptr->next, foundItem, target );} Advances pointer in a recursive function call 40
41. 41. Recursion on a Linked List (cont.)1 void discount( Node<T> *ptr )2 {3 if ( ptr != NULL ) {4 ptr->info.price -= 0.1 * ( ptr->info.price );5 discount( ptr->next );6 }7 }Discounts all Car prices in a linked list by 10% 41
42. 42. Recursion on a Linked List (cont.)1 void discount( Node<T> *ptr )2 {3 if ( ptr != NULL ) {4 ptr->info.price -= 0.1 * ( ptr->info.price );5 discount( ptr->next );6 }7 }Recursive call – no return necessary (void return type) 42
43. 43. Recursion on a Linked List (cont.)1 void discount( Node<T> *ptr )2 {3 if ( ptr != NULL ) {4 ptr->info.price -= 0.1 * ( ptr->info.price );5 discount( ptr->next );6 }7 }Where is the base case? 43
44. 44. Recursion on Linked Lists (cont.) 1 void discount( Node<T> *ptr ) 2 { 3 if ( ptr != NULL ) { 4 ptr->info.price -= 0.1 * ( ptr->info.price ); 5 discount( ptr->next ); 6 } 7 }The base case exists, it just does not need to be written.When ptr == NULL, it is the base case. The only thing thatneeds to be done for the base case is to return. 44
45. 45. Tower of Hanoi• Three pegs are provided to hold disks. The first peg has a stack of n disks that are arranged from bottom to top by decreasing size.• The goal is to move the stack from the first peg to the last peg under the following rules: – Exactly one disk is moved at a time. – A larger disk should never be placed above a smaller disk. 45
46. 46. Tower of Hanoi (cont.)• Example: Initial stack of 3 disks all placed at Peg A. 1 2 3 Peg A Peg B Peg C 46
47. 47. Tower of Hanoi (cont.)• Step 1: Move disk 1 from Peg A to Peg C. 2 3 1 Peg A Peg B Peg C 47
48. 48. Tower of Hanoi (cont.)• Step 2: Move disk 2 from Peg A to Peg B. 3 2 1 Peg A Peg B Peg C 48
49. 49. Tower of Hanoi (cont.)• Step 3: Move disk 1 from Peg C to Peg B. 1 3 2 Peg A Peg B Peg C 49
50. 50. Tower of Hanoi (cont.)• Step 4: Move disk 3 from Peg A to Peg C. 1 2 3 Peg A Peg B Peg C 50
51. 51. Tower of Hanoi (cont.)• Step 5: Move disk 1 from Peg B to Peg A. 1 2 3 Peg A Peg B Peg C 51
52. 52. Tower of Hanoi (cont.)• Step 6: Move disk 2 from Peg B to Peg C. 2 1 3 Peg A Peg B Peg C 52
53. 53. Tower of Hanoi (cont.)• Step 7: Move disk 1 from Peg A to Peg C. 1 2 3 Peg A Peg B Peg C 53
54. 54. Tower of Hanoi (cont.)• Goal achieve: The stack is moved to Peg C. 1 2 3 Peg A Peg B Peg C 54
55. 55. Tower of Hanoi (cont.)• If there is 1 disk in the stack, the total number of moves is 1 (21 - 1).• If 2 disks … moves is 3 (22 - 1).• If 3 disks … moves is 7(23 - 1).• Hence, if there are n disks…, the total number of moves is 2n – 1. 55
56. 56. Tower of Hanoi (cont.)1 void TowerOfHanoi (int n,2 string source, string temp, string destination) {3 if (n == 1) // base case4 cout << "Move disk " << n << " from "5 << source << " to " << destination << endl;6 else {7 TowerOfHanoi (n - 1, source, destination, temp);8 cout << "Move disk " << n << " from "9 << source << " to " << destination << endl;10 TowerOfHanoi (n - 1, destination, temp, source);11 }12 } 56
57. 57. References• Childs, J. S. (2008). Recursion. C++ Classes and Data Structures. Prentice Hall. 57