Ce este recursivitatea
O funcție este recursivă dacă se apelează pe ea însăși. Orice funcție recursivă corectă are:
- cazul de bază: condiția de oprire, fără autoapel;
- cazul general: autoapelul pe o problemă MAI MICĂ.
Exemplul fundamental: factorialul
Factorialul, recursiv
#include <iostream>
using namespace std;
int fact(int n) {
if (n == 0) return 1;
return n * fact(n - 1);
}
int main() {
cout << fact(5);
return 0;
}Atenție: In Pascal rezultatul functiei se atribuie numelui ei, nu se scrie return. Aici fact e longint, fiindca factorialul creste foarte repede.
Urmărirea pentru fact(4): .
Alte exemple clasice
Suma cifrelor:
Suma cifrelor, recursiv
#include <iostream>
using namespace std;
int sc(int n) {
if (n == 0) return 0;
return n % 10 + sc(n / 10);
}
int main() {
cout << sc(4729);
return 0;
}Atenție: Impartirea intreaga se scrie / in C si C++ pentru intregi, div in Pascal si // in Python. Cu / simplu, Python ar da un numar zecimal si recursivitatea nu s-ar opri.
sc(275) = 5 + sc(27) = 5 + 7 + sc(2) = 5 + 7 + 2 + sc(0) = 14.
Cel mai mare divizor comun (Euclid):
Cel mai mare divizor comun, recursiv
#include <iostream>
using namespace std;
int cmmdc(int a, int b) {
if (b == 0) return a;
return cmmdc(b, a % b);
}
int main() {
cout << cmmdc(48, 18);
return 0;
}cmmdc(24, 36) = cmmdc(36, 24) = cmmdc(24, 12) = cmmdc(12, 0) = 12.
Cum urmărești un apel la BAC
- Scrie fiecare apel pe un rând, cu argumentele lui.
- Coboară până la cazul de bază.
- Urcă înapoi înlocuind fiecare apel cu valoarea returnată.
Atenție
Fără caz de bază (sau cu autoapel care NU micșorează problema), funcția se apelează la infinit: stack overflow. La subiectele de tip "ce afișează", verifică întâi condiția de oprire.
Reține
Orice funcție recursivă are un caz de bază (oprire, fără autoapel) și un caz general (autoapel pe o problemă mai mică). Valori de verificare: fact(0) = 1, sc(275) = 14, cmmdc(24, 36) = 12.
Greșeli frecvente
- Ordinea contează:
return n * fact(n-1)înmulțește DUPĂ întoarcerea din apel. - La afișări recursive, instrucțiunile de DINAINTE de autoapel se execută la coborâre, cele de DUPĂ la întoarcere: de aici apar afișările "inversate".
fact(0)este 1, nu 0.