Why is fib2 faster than fib? I said in class that fib is exponential and fib2 is linear. (Actually, I said fib was quadratic, but I was wrong.) What does this mean?
A linear algorithm is one that takes time proportional to the size of its input. In this sense, fib2 is linear in n. Let's say the body of fib2, except for the recursive call to fib2, takes at most time T. Thus, fib2(1) and fib2(0) both take time less than T. fib2(2) takes time T plus the time for the recursive call to fib2(1); thus it takes time T+T = 2T. Similarly fib2(3) takes time T+2T = 3T. In general fib2(n) takes time nT. A constant T times n is a linear function of n. Formally, we can say fib2 is O(n). You'll see this notation used in later classes and throughout your career.
The analysis of the simpler fib function is more complicated. An exponential algorithm is one that takes time proportional to some constant raised to the power of the size of its input. In this sense, fib is exponential in n. Once again, let's say the body of fib, except for the recursive calls, takes at most time T. Thus, fib(1) and fib(0) both take time less than T. But now fib(2) takes time T for itself plus 2T for the two recursive calls to fib, or 3T. In general fib(n) takes time S(n) = T + S(n-1) + S(n-2). Note how this formula mirrors the fib function itself. Indeed, S(n) = T*F(n), where F(n) is the nth Fibonacci number. Note that F(n) is greater than 2*F(n-1), but less than 2*F(n-2). F(n) thus does not quite double with every increase of n by 1, but it does more than double with every increase of n by 2. That is, 2^n > F(n) > 2^(n/2) = sqrt(2)^n = 1.4142^n. In fact, one can show using more sophisticated mathematics (see CSE 2320) that F(n) is about 1.618^n for sufficiently large n. Since F(n) is exponential in n, S(n) is exponential in n.