Lecture 02: Recursion I

Outline

  1. Intro to Recursion
  2. Activity: Fibonacci numbers
  3. Comparing Recursion and Iteration

Code Used in This Lecture

Recursion

Recursion

  • Lab 01, you use iteration (looping) to solve a problem (printing something on the screen many times)
      for int(i = 0; i < max; i++) {
        // do something
      }
    
  • Some problems are naturally recursive: solution of the whole problem can be reduced to solving the same problem (possibly several times) on a smaller instance.
      public int doSomething(int n) {
        // some code
        doSomething(n - 1); // recursive function call
        // some more code
        return something;
      }
    

Example: Factorial

For a positive integer $n$, the factorial function, $f(n) = n!$ is defined to be:

  • \[f(n) = n \cdot (n-1) \cdot (n - 2) \cdots 2 \cdot 1\]

Compute some factorials!

Factorial: Recursive Formula

For any $n \geq 2$, we have

  • \[f(n) = \begin{cases} 1 &\text{ if } n = 1\\ n \cdot f(n-1) &\text{ if } n > 1.\end{cases}\]

This is a recursive formula!

Factorial in Code

    private static int factorial(int n) {
        if (n <= 1) {
          return 1;
        }
    
        return n * factorial(n - 1);
    }

Download Factorial.java

How does this work?

    private static int factorial(int n) {
        if (n == 1) {
          return 1;
        }
    
        return n * factorial(n - 1);
    }

Compute factorial(4) by hand!

Fibonacci Numbers

The Fibonacci numbers are the sequence of numbers

$1, 1, 2, 3, 5, 8, 13, 21, \ldots$

where each number is the sum of the previous two.

Activity. Write a method that computes the $n$-th Fibonacci number for a positive integer (long) $n$.

Two Approaches

  • Iterative (computation using a loop)
  • Recursive

Question. Which is better?

Let’s Test Their Performance!

Download Fibonacci.java

Testing the Performance of Factorials

Download FactorialTest.java

A Question

What makes recursive Fibonacci slow, while recursive factorial is fairly fast?

Recursive Fibonacci

private static long fib (long n) {
    if (n <= 2)
        return 1;
	
    return fib(n-1) + fib(n-2);
}

Recursive Factorial

    private static int factorial(int n) {
        if (n <= 1) {
          return 1;
        }
    
        return n * factorial(n - 1);
    }

Upcoming

Three morals, three questions

  1. Recursion may give simple code, but may be less efficient
    • How can we determine which is better?
  2. Fibonacci numbers grow too fast
    • How can we design a better solution?
  3. We should do better at error checking
    • Can we validate input while running?