Repetition: Major task of many algorithms
Example: Printing a String n times with recursion
print (int n) { if (n != 1) { print(n - 1); } System.out.println("hello"); }
Note: LISP
- Initially didn’t have normal loops, everything had to be thought of recursively.
Recursion: Problem-solving process of breaking a problem into identical but smaller problems.
Tail Recursion: When the last action performed by a method is a recursive call.
Indirect Recursion: When a(x) calls b(x) and b(x) calls a(x)
Example: Count down from a positive integer
public static void countown(int integer) { System.out.println(integer); if (integer > 1) { countDown(integer - 1) } }
- This uses tail recursion, as the last thing it does is call itself.
Design Guidelines:
Note: If you recurse forever, you’ll encounter a program stack overflow
- In Java, you can only be approx. 60 calls deep before you reach this.
Example: Factorial
int fact(int n) { if (n == 0) { // Terminal case return 1; } else { // Recursive case return n*fact(n-1); } }
Example: Printing a singly-linked list in reverse order with recursion and exposing it to a client
// What we provide to the client public void print () { print(head) } // Private method we use that lets us access out Node inner-class private void print (Node node) { if (node != null) { print(node.next); System.out.println(node.data); } }
Common Mistake: Using iteration instead of an if statement in a recursive function.
Some problems like the Tower of Hanoi or finding the shortest path or 8-Queen problem are made easier through recursion because it makes backtracking easier.
Some algorithms like Fibonacci are very inefficient when solved recursively.