Pe scurt
Unele calcule pot fi scrise atât cu apeluri recursive, cât și cu o buclă. Factorialul lui 4 se obține prin în ambele forme. Alegerea ține de claritatea problemei, de memoria folosită și de limite: apelurile recursive ocupă stivă, pe când o buclă simplă poate folosi doar câteva variabile.
În detaliu
Multe calcule se pot scrie în două moduri echivalente: recursiv, cu un subprogram care se apelează pe el însuși, și iterativ, cu un ciclu. Alegerea ține de claritatea soluției, de memorie și de timp. Varianta iterativă păstrează de obicei câteva variabile și folosește spațiu auxiliar constant. Varianta recursivă păstrează câte un cadru pe stivă pentru fiecare apel activ, deci cere spațiu proporțional cu adâncimea recursiei, iar o recursie foarte adâncă poate umple stiva. În schimb, pentru definiții care au natură recursivă (arbori, divizarea problemei în subprobleme), soluția recursivă este mai scurtă și mai ușor de verificat. Orice calcul recursiv poate fi simulat iterativ cu o stivă explicită, iar orice ciclu se poate rescrie recursiv.
Exemplul 1 — factorialul în ambele forme.
#include <iostream>
using namespace std;
long long factRec(int n) { return n == 0 ? 1 : n * factRec(n - 1); }
long long factIter(int n) {
long long p = 1;
for (int i = 2; i <= n; ++i)
p *= i;
return p;
}
int main() {
cout << factRec(4) << " " << factIter(4);
return 0;
}
Programul afișează 24 24. Varianta recursivă face apeluri și păstrează cadre pe stivă; varianta iterativă face înmulțiri și folosește două variabile. Ambele au timp proporțional cu , dar cea iterativă are memorie auxiliară constantă, pe când cea recursivă are memorie proporțională cu .
Exemplul 2 — Fibonacci: recursie naivă contra iterație. Definiția , scrisă direct, apelează de două ori funcția și recalculează aceleași valori: pentru se fac 177 de apeluri, iar pentru se fac 21 891. Varianta iterativă păstrează ultimii doi termeni și face pași, deci pentru face 20 de adunări, față de 21 891 de apeluri:
long long fibIter(int n) {
long long a = 0, b = 1;
for (int i = 0; i < n; ++i) {
long long urmator = a + b;
a = b;
b = urmator;
}
return a;
}
Pentru funcția întoarce 55, aceeași valoare ca recursia, dar cu zece iterații în loc de 177 de apeluri. Diferența dintre un număr exponențial și unul liniar de pași apare doar la varianta recursivă naivă; o recursie care nu repetă subproblemele, ca factorialul, are același număr de pași ca ciclul.
Exemplul 3 — suma cifrelor, recursiv și iterativ. Varianta recursivă n == 0 ? 0 : n % 10 + sumaCifre(n / 10) și ciclul while (n > 0) { s += n % 10; n /= 10; } dau amândouă 16 pentru . Aici ciclul este mai scurt și nu cere stivă; recursia este utilă când pasul seamănă cu definiția matematică. La o problemă pe arbore, de exemplu parcurgerea tuturor nodurilor, recursia este mai simplă decât ciclul cu stivă explicită.
Exemplul 4 — cel mai mare divizor comun, cu invariant și condiție de oprire. Algoritmul lui Euclid se bazează pe egalitatea , care rămâne adevărată la fiecare pas (invariantul), și se oprește când al doilea număr devine 0.
int cmmdcRec(int a, int b) { return b == 0 ? a : cmmdcRec(b, a % b); }
int cmmdcIter(int a, int b) {
while (b != 0) {
int r = a % b;
a = b;
b = r;
}
return a;
}
Pentru și perechile succesive sunt , , , , deci ambele funcții întorc 6. Recursia are patru apeluri active la un moment dat, iar ciclul folosește trei variabile. Apelul recursiv este ultima operație a funcției, așa că ciclul este o traducere directă a lui: parametrii noi se atribuie variabilelor, iar condiția de oprire devine negata condiției ciclului. Dacă se omite cazul b == 0, apelurile continuă până la umplerea stivei, iar programul se oprește cu eroare.
Greșeli frecvente
- Greșit: varianta recursivă este întotdeauna mai rapidă decât cea iterativă.Corect: de multe ori este la fel de rapidă, iar la Fibonacci naiv este exponențial mai lentă.
- Greșit: o recursie nu poate fi rescrisă cu un ciclu.Corect: poate fi rescrisă iterativ, uneori cu o stivă explicită.
- Greșit: recursia nu consumă memorie.Corect: fiecare apel activ ocupă un cadru pe stivă.
Testează-te pe această lecție
Lecția o citești aici, fără cont. Testele pe lecții și capitole sunt în cont, cu grile originale Didaxis și explicația fiecăreia: gratuit 10 grile pe zi, fără limită cu Premium, 49 de lei pe lună pentru fiecare copil.
Înainte și după
Surse și referințe
Redactare proprie, conform programei:
- OMECI 5099/2009, anexa 5, Informatică, p. 4–5, clasa X intensiv; rocnee.eu
- OMECI 5099/2009, anexa 5, Informatică, p. 4–5, clasa XI; plan de încadrare: OMEC 7723/2024, anexa 2, tabelele 1–25, legislatie.just.ro; filiera tehnologică: OMEC 7724/2024, anexa 4, tabelul calificării, legislatie.just.ro
Documente consultate
- Programa școlară de informatică, clasa a XI-a (OMECI 5099/2009, anexa 5), CNCE; rocnee.eu
- Programa de bacalaureat la informatică, matematică-informatică (anexa 2 la OMECTS 4800/2010), Ministerul Educației, p. 4–5; edu.ro
- Programele școlare noi de informatică pentru clasele X–XII (OMEC 4370/2026, MO 591 bis/20.07.2026), CNCE; rocnee.eu
- Subiectele și baremele Bacalaureatului 2026; subiecte2026.edu.ro
Desene: Redactare proprie (desen original), conform Programa școlară de informatică, clasa a XI-a (OMECI 5099/2009, anexa 5), CNCE; rocnee.eu
