Eine Fibbonacci-Sequenz ist eine Sequenz, die das Ergebnis einer Zahl summiert, wenn sie zum vorherigen Ergebnis hinzugefügt wird, beginnend mit 1.
so.. 1 + 1 = 2
2 + 3 = 5
3 + 5 = 8
5 + 8 = 13
8 + 13 = 21
Sobald wir verstanden haben, was Fibbonacci ist, können wir beginnen, den Code aufzuschlüsseln.
public int fibonacci(int n) {
if(n == 0)
return 0;
else if(n == 1)
return 1;
else
return fibonacci(n - 1) + fibonacci(n - 2);
}
Die erste if-Anweisung sucht nach einem Basisfall, in dem die Schleife ausbrechen kann. Die else if-Anweisung darunter macht dasselbe, könnte aber so umgeschrieben werden ...
public int fibonacci(int n) {
if(n < 2)
return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}
Nachdem ein Basisfall erstellt wurde, müssen wir den Aufrufstapel verstehen. Ihr erster Aufruf von "Fibonacci" wird der letzte sein, der auf dem Stapel (Reihenfolge der Aufrufe) aufgelöst wird, da sie in der umgekehrten Reihenfolge aufgelöst werden, aus der sie aufgerufen wurden. Die letzte aufgerufene Methode wird zuerst aufgelöst, dann die letzte, die vor dieser aufgerufen wird, und so weiter ...
Alle Anrufe werden also zuerst getätigt, bevor mit diesen Ergebnissen etwas "berechnet" wird. Bei einer Eingabe von 8 erwarten wir eine Ausgabe von 21 (siehe Tabelle oben).
Fibonacci (n - 1) wird so lange aufgerufen, bis es den Basisfall erreicht, dann wird Fibonacci (n - 2) aufgerufen, bis es den Basisfall erreicht. Wenn der Stapel beginnt, das Ergebnis in umgekehrter Reihenfolge zu summieren, sieht das Ergebnis so aus ...
1 + 1 = 1 ---- last call of the stack (hits a base case).
2 + 1 = 3 ---- Next level of the stack (resolving backwards).
2 + 3 = 5 ---- Next level of the stack (continuing to resolve).
Sie sprudeln weiter (werden rückwärts aufgelöst), bis die richtige Summe an den ersten Aufruf im Stapel zurückgegeben wird und Sie auf diese Weise Ihre Antwort erhalten.
Allerdings ist dieser Algorithmus sehr ineffizient, da er für jeden Zweig, in den sich der Code aufteilt, das gleiche Ergebnis berechnet. Ein viel besserer Ansatz ist ein "Bottom-up" -Ansatz, bei dem keine Memoisierung (Caching) oder Rekursion (Deep Call Stack) erforderlich ist.
Wie so ...
static int BottomUpFib(int current)
{
if (current < 2) return current;
int fib = 1;
int last = 1;
for (int i = 2; i < current; i++)
{
int temp = fib;
fib += last;
last = temp;
}
return fib;
}