The Fibonnaci sequence is one where each term equals the sum of the two previous terms.
Now, if each term is the sum of the two previous ones, then:
T(n) = T(n-1) + T(n-2)
By the way, that's exactly what we got in the algorithm you gave:
return fib(n-1) + fib(n-2);
That is, the sum of the two previous terms. Therefore, the T(n) = 1 + T(n-1) + T(n-2)
formula is simply wrong. This " 1 +
" that is there should not exist.
Finally, T(0) = 0
and T(1) = 1
are the initial terms of the sequence. if (n<2) return n;
is responsible for dealing with such cases.
The implementation of this by direct and simple recursion is not efficient . The reason is that when calculating T(n)
, we have two recursive calls to T instead of just one (as in factorial). Thus, each recursive call to T opens two other recursive calls, and each of these two calls opens two more, and each opens two more, and the business ends up growing more or less exponentially (it just is not exactly exponential because the recursive sub-calls have different sizes, then the first one is heavier than the second).
The exponential time burst can be avoided by verifying that when computing T(n-1)
, we also have to indirectly calculate T(n-2)
in the process, so it is not necessary to calculate T(n-2)
twice (one as part of T(n-1)
and the other directly). So if we can reuse the T(n-2)
calculation to calculate the T(n-1)
, the number of calls would go to linear instead of exponential.
One way to fix the recursive algorithm is to cache previously computed values to avoid having to recompute them:
// Crie um array grande o suficiente e inicialize todas as posições com -1.
int cache[] = ...;
int fib(int n) {
if (n < 2) return n;
if (cache[n] == -1) cache[n] = fib(n - 1) + fib(n - 2);
return cache[n];
}
Another efficient way would be to eliminate recursion, which has the advantage of not needing the cache. But hence the recurrence relation is no longer clearly visible in the resulting algorithm:
int fib(int n) {
if (n < 2) return n;
int a = 0, b = 1;
for (int i = 1; i < n; i++) {
int c = b;
b = a + b;
a = c;
}
return b;
}