330 likes | 483 Views
Data Structures CSCI 132, Spring 2014 Lecture 16 Tail Recursion. Recall Recursive Skating. void skateLaps( int n) { if ( n < = 0 ) { //do nothing } else { cout << "Skating 1 lap." << endl; skateLaps( n - 1); } }. Base Case. General Case. Tail Recursion.
E N D
Data StructuresCSCI 132, Spring 2014Lecture 16Tail Recursion
Recall Recursive Skating void skateLaps( int n) { if ( n < = 0 ) { //do nothing } else { cout << "Skating 1 lap." << endl; skateLaps( n - 1); } } Base Case General Case
Tail Recursion • When the recursive function call is the last thing that occurs in the recursive function, this is called a Tail Recursion. • In a tail recursion, there are no pending operations. • Any tail recursion can be written as an iteration (a loop).
Iterating skateLaps void skateLaps( int n) { while (n > 0 ) { cout << "Skating 1 lap." << endl; n = n - 1; } }
Factorial Revisited int Fact (int n) { if (n <= 0) { return 1; } else { return n * Fact (n - 1); } } Is this a tail recursion? No. Can we write this as a tail recursion? Yes! Keep track of the answer in a parameter that gets passed on.
Tail Recursion Factorial int factIter (int n) { //Helper function to initialize ans return factTail(n, 1); } int factTail (int num, int ans) { if (num <= 0) { return ans; } else { return factTail(num - 1, num*ans); } }
Execution of FactTail num ans num*ans Function Calls 4 1 4 Fact(4, 1):24 3 4 12 Fact(3, 4):24 2 12 24 Fact(2, 12):24 1 24 24 Fact(1, 24):24 0 24 (returned) Fact(0, 24):24
Writing factTail as an iteration int factWhile (int n) { }
Writing factTail as an iteration int factWhile (int n) { int num = n; int ans = 1; while (num > 0) { ans = ans * num; num = num - 1; } return ans; }
Fibonacci in C++ code int Fib( int n ) { if (n < 2) { return n; } else { return Fib(n-1) + Fib(n -2); } }
Fibonacci as a Tail Recursion (fib(i) + fib(i-1)) n i fib(i-1) fib(i) fib(i_next) 5 1 0 1 1 5 2 1 1 2 5 3 1 2 3 5 4 2 3 5 5 5 3 5 8 Pass values as parameters of the recursive function: n, i, fibIminus1, fibI (we will work on this in lab).
The Tower of Hanoi Setup: A stack of rings in order of largest to smallest is on one of three pegs (largest on the bottom, smallest on the top). Object: Move stack from one peg to another peg following these rules: 1) Cannot put a ring on top of a smaller ring. 2) Can only move 1 ring at a time.
Tower of Hanoi Demo B C A
Tower of Hanoi Demo B C A
Tower of Hanoi Demo B C A
Tower of Hanoi Demo B C A
Tower of Hanoi Demo B C A
Tower of Hanoi Demo B C A
Tower of Hanoi Demo B C A
Tower of Hanoi Demo B C A
Tower of Hanoi Demo B C A
Tower of Hanoi Demo B C A
Tower of Hanoi Demo B C A
Tower of Hanoi Demo B C A
Tower of Hanoi Demo B C A
Tower of Hanoi Demo B C A
Tower of Hanoi Demo B C A
Tower of Hanoi Demo B C A
Strategy for Tower of Hanoi 1) Move top (n-1) rings from origin to spare (following all the rules). 2) Move bottom ring from origin to destination 3) Move top (n-1) rings from spare to destination (following all the rules).
Implementing Tower of Hanoi void hanoi(int n, char start, char end, char spare) { if (n < = 0) { //do nothing } else { hanoi(n-1, start, spare, end); cout << "Move disk " << n << "from " << start << " to " << end << endl; hanoi(n-1, spare, end, start); } } //Outputs sequence of moves to solve tower of hanoi!
Invocation Tree for hanoi nodes 20 21 22 23 24 How long will it take to move a tower 100 rings high?