Recursion Definition: A method that calls itself. Examples public int factorial(int n) { if (n==1) return 1; return n * factorial(n-1); } public void hello(int n) { if (n>=0) { System.out.println("Hello"); hello(n-1);
Addr of the println() call. Why does it work? Example call: int i = do(9, -1); System.out.println(i); Declaration: public int do(int n,int k) { int num = 5; return n + k + num; } Java creates an activation record for every method call Definition: An activation record is a block of memory on the call stack containing parameter values, local variables, the return address, and return value. The activation record exists only while the method executes The activation record is released when the method returns A stack is a last-in first-out list A list is an ordered collection of elements. Activation Record n: 9 k: -1 num: 5 valueToReturn: 13 Return addr: Addr of the println() call.
Another Example Simple Example: Notes: Question: See ../demos/SumByRecursion.java Notes: The then branch of the 'if' statement is the non-recursive part (the basis case) The else branch contains the recursive call A stack overflow occurs if the basis case never executes Question: What happens if startIndex is negative?
Designing a recursive method There are two requirements Define the basis case Define the relationship between the problem and one or more smaller problems of the same kind When is recursion beneficial? Recursive algorithms are ALWAYS slower than their non-recursive counterparts. Why? Recursive algorithms can often reduce a problem to just a few statements. Non-recursive algorithms can be sometimes more difficult to program and maintain. Recursion is useful when the recursion step significantly reduces the problem size.
Some more examples Fibonacci sequence: 1, 1, 2, 3, 5, 8, … Basis case: n<2; Recursive step: return f(n-2)+f(n-1) Greatest common denominator Basis case: y%x = 0; Recursive step: return gcd(y%x,x) See ../demos/GCD.java Palindrome Tester Basis case: length <=1 or first character <> last character Recursive step: pal(s.substring(1,s.length()-2)) Print a string (Question: How would you reverse a string?) Basis case: length=1; Recursive step: print char 0 and call with remainder
Towers of Hanoi A disk is represented by its size 0 == smallest A tower is represented by a char: A, B, or C src == tower holding the disks to be moved dest == tower to which to move the disks spare == tower to use as a temporary holding place https://www.cs.cmu.edu/~cburch/survey/recurse/hanoiimpl.html FUNCTION recursiveMove(disk, src, dest, spare): IF disk == 0, THEN: move disk from src to dest ELSE: recursiveMove(disk - 1, src, spare, dest) recursiveMove(disk - 1, spare, dest, src) END IF
Graphics and Fractals Definition: A recursive geometric pattern Examples: Drawing a tree visually Sierpinski's triangles Koch's Snowflake - https://en.wikipedia.org/wiki/Koch_snowflake See demos/KochFlakeLeaf.java Mandelbrot set – uses complex numbers Our lab4: Recursively generate an image