Data Structures And Algorithms Recursion Eng. Anis Nazer First Semester 2016-2017
Recursion Recursion: to define something in terms of itself Example: factorial n!={ 1 n=0 n (n 1)! n>0
Recursion Example: factorial of 4 = 4 x factorial of 3 factorial of 3 = 3 x factorial of 2 factorial of 2 = 2 x factorial of 1 factorial of 1 = 1 x factorial of 0 factorial of 0 = 1
Recursive function A recursive function is a function that calls itself, directly or indirectrly int f() {.. f().. }
Recursion Direct recursion: function calls itself Indirect recursion: function1 calls function2 function2 calls function3 function3 calls function1
Recursion Recursion is like a loop To stop the recursion, a base case should be written The base case does not call the function and stops the recursion
Example Factorial: int fact(int n) { if ( n == 0 ) return 1; else { int r = n * fact( n 1 ); return r; } }
Example what happens if you call: cout << fact(3) ; main().. cout << fact(3) ;.. 6 3 fact(3) n 3 r = 3 * fact(2) return 6; 2 fact(2) 2 n 2 r = 2 * fact(1) return 2; 1 fact(1) 1 n 1 r = 1 * fact(0) return 1; 0 fact(0) 1 n return 1; 0
Function calls Activation record: is the function data, local variables return address, return value etc When a function is called: the operating system pushes the activation record in a runtime stack When a function returns: the operating system pops the activation record from the runtime stack The runtime stack is managed by the operating system
Example What does this function do? int fun(int x, int y) { if ( y == 1 ) return x; else { int r = x + fun( x, y 1 ); return r; } }
Fibonacci series Fibonacci series: 0, 1, 1, 2, 3, 5, 8, 13, 21, start with: 0, 1 each number is the sum of the previous two numbers
Fibonacci series the function: fib(n)={ n n<2 fib(n 1)+fib(n 2) n 2
Fibonacci series fib(0) = 0 fib(1) = 1 fib(2) = fib(1) + fib(0) = 1 + 0 = 1 fib(3) = fib(2) + fib(1) = 1 + 1 = 2 fib(4) = fib(3) + fib(2) = 2 + 1 = 3 fib(6) =?
Fibonacci series Fibonacci can be easily implemented using a recursive function: int fib( int n ) { if ( n < 2 ) return n; else return fib(n 1) + fib(n 2); }
Fibonacci series How many function calls are performed if you call fib(4)? fib(4) fib(3) fib(2) fib(2) fib(1) fib(1) fib(0) fib(1) fib(0)
Fibonacci series How many function calls are performed if you call fib(5)? fib(5) = fib(4) + fib(3) fib(4) 9 function calls fib(3) 5 function calls => 14 function calls the number of function calls is exponential which is very inefficient O(2 n )
Fibonacci series Fibonacci can be written using a loop: int fib( int n ) { if ( n < 2 ) return n; else { int older = 0, old = 1, sum = 0, i = 2; while ( i <= n ) { sum = old + older; older = old; old = sum; i++; } return sum; } }
Example What does the function do? void rev() { char c; cin.get(c); if ( c == '\n' ) return; else { rev(); cout.put(c); } return; }
Tail Recursion Tail Recursion: recursive call is the last statement in the function Tail recursion can be easily written using a loop Example: factorial()
Non-Tail recursion The recursive call is not the last statement in the function Non-Tail recursion can be written using a loop but you have to use a stack example: reverse() Try writing reverse() using a loop
Nested Recursion The recursive function calls itself as a parameter Example: h(n)={ 0 n=0 n n>4 h(2+h(2n)) n 4 what is h(3)?
Recursion Why use recursion since you can use a loop? Some problems are recursive by definition Some problems are solved easily using recursion example: towers of Hanoi
Towers of Hanoi A B C
Towers of Hanoi Game where you have three towers (A, B, C) A number of disks of different sizes are stacked on tower A You have to move the disks from tower A to tower C Rules: move a single disk per move you cannot put a large disk on top of a smaller disk
Towers of Hanoi Take the case of 3 disks: 1) move 2 disks from A to B 2) move disk from A to C 3) move 2 disks from B to C
Towers of Hanoi Take the case of 4 disks: 1) move 3 disks from A to B 2) move disk from A to C 3) move 3 disks from B to C
Towers of Hanoi Take the case of n disks: 1) move (n-1) disks from A to B 2) move disk from A to C 3) move (n-1) disks from B to C
Towers of Hanoi Write a function that will solve this game?? parameters: n: number of disks src: the source tower dst: the destination tower tmp: the third tower
Towers of Hanoi if you have one disk only: move it from source to destination if you have n disks ( n > 1 ) 1) move (n-1) disks from source to tmp 2) move disk from source to destination 3) move (n-1) disks from tmp to destination
Towers of Hanoi void move(int n, char src, char dst, char tmp) { if ( n == 1 ) cout << "move from " << src << " to " << dst << endl; else { move(n 1, src, tmp, dst); move(1, src, dst, tmp); move(n 1, tmp, dst, src); } }
Towers of Hanoi A myth says that the world will end after you move a tower of 64 disks...?? 64 disks need 2^64 = 1.844674407 10¹ ⁹ moves Assuming 10 moves per second. you need. 58,494,241 century not in our lifetime :)