Stacks & Recursion
Stack Linear data structure Can only be accessed from one end Very useful when data has to stored and then retrieved in the reverse order. Called LAST IN FIRST OUT (LIFO)
LIFO : Last In First Out Stack 10 6 9
Stacks Stack 10 6 9 LIFO : Last In First Out
Operations By Adam Drozdek
RECURSIVE STRUCTURE Sierpinski_Triangle from www.wikipedia.org
Recursive Definition An object is defined in terms of smaller version of itself A problem is decomposed into simpler subproblems of the same kind Recursion is the process in which repetition in a “self-similar” manner Generally used to define functions or sequences of numbers Has two parts Base Case / Anchor Case / Ground Case Define the basic building blocks Rules / General Case Define how objects / elements can be built from basic elements or already constructed objects Serves two purposes Generating new elements Testing whether an element belongs to a set
Will test if a number is member of series Examples Factorials n! = 1 if n=0 n! = n(n-1)! if n> 0 This definition will evaluate the factorial of a number The set of natural numbers 0 N If n N then (n+1) N There are no other natural numbers This definition will generate natural numbers Will test if a number is member of series Will generate numbers
Activation Records/Stack Frame Recursive Function Recursion means having the characteristic of coming up again and again A function that invokes itself by making a call to itself is called a recursive function Direct Recursion: When a function calls itself Indirect Recursion: When A calls B and B calls A Activation Records/Stack Frame The state of each function is characterized by an activation record. It is the private pool of information for a function. It has the following information: Parameters and local variables: of the function Dynamic link: Link to the calling function’s activation record Return Address: Caller function’s return address Runtime Stack Runtime stack is a stack whose each element is the activation records of the different functions being called during the running of the program
Example int factorial(n) void main() { { int fact = 1; if (n==0) return fact; else { fact = n*factorial(n-1); return fact; } void main() { int answer = factorial(3); cout << answer; } Factorial(0) Factorial(1) Factorial(2) Factorial(3) Main() fact = 1 fact = 1 * factorial(0) fact = 1*1=1 answer = factorial (3) fact = 3 * factorial(2) fact = 2 * factorial(1) fact = 2 * factorial(1) answer = factorial (3) fact = 3 * factorial(2) fact = 2 * 1=2 fact = 3 * factorial(2) answer = factorial (3) fact = 3 * 2 = 6 answer = factorial (3) answer = 6
Towers of Hanoi Watch animation with 4 disks!!! Pictures and animation from: www.wikipedia.org void Hanoi(int N,char src,char dest,char intermediate) { if (N>0) { //move top n-1 disks from ‘src’ to ‘intermediate’ //using ‘dest’as intermediate location Hanoi(N-1,src,intermediate,dest); //move the bottom disk from ‘src’ to ‘dest’ Move(src,dest); //now move the rest of N-1 disks from ‘intermediate’ //to ‘dest’ using ‘src’ as intermediate location Hanoi(N-1,intermediate,dest,src); }
How it is working??? Lets trace for Hanoi(3,’A’,’C’,’B’) Sequence of moves: Move(A,B) Move(AC) Move(B,C) Move(B,A) Move(A,C) Hanoi(0,A,C,B) Move(A,B) Hanoi(0,C,B,A) Hanoi(1,A,B,C) Move(A,C) Hanoi(1,B,C,A) See animation!!! Hanoi(2,A,C,B) Move(A,B) Hanoi(2,B,C,A) Hanoi(0,B,A,C) Move(B,C) Hanoi(0,A,C,B) Hanoi(3,A,B,C) Hanoi(0,B,C,A) Move(B,A) Hanoi(0,C,A,B) Hanoi(1,B,A,C) Move(B,C) Hanoi(1,A,C,B) Hanoi(0,A,B,C) Move(A,C) Hanoi(0,B,C,A)
Tail Recursion Use of only one recursive call at the very end of the function implementation. Useful in logic programming languages like prolog. Non-Tail Recursion When the recursive call is NOT tail recursion
More examples, which you can try… Fibonacci Series Linear search Binary search Reverse items of an array