SUBPROGRAME RECURSIVE
Spunem despre un subprogram că este recursiv dacă conține în definirea sa un apel la el însuși.
Astfel putem avea două tipuri de recursivitate:
- Directă (atunci când subprogramul conține un apel la el însuși)
- Indirectă (atunci când subprogramul P apelează un subprogram Q care la rândul să conține în definirea sa un
apel la subprogramul P).
|
Structura unei funcţii recursive
tip nume_funcţie (lista de parameri) {
.................
nume_funcţie (lista de parametri);
//funcţia conține un apel la ea însăși
..................
}
|
Structura unei funcţii recursive indirect apelate prin
intermediul unei alte funcţii:
tip B(lista de parameri) {
.................
A(lista de parametri); //funcţia B apelează funcţia A ..................
}
tip A(lista de parameri) //funcţia A este recursivă şi apelează funcţia B
{.................
if(condiţie de
continuare)
.................
B(lista de parametri);
.................. } |
Majoritatea algoritmilor repetitivi se pot implementa atât în varianta nerecursivă,
folosind cicluri, cât și în varianta recursivă.
Varianta recursivă este recomandată în special pentru problemele definite prin relații de recurentă, care permit o formulare a rezultatelor mult mai clară și mai
concisă.
Un subprogram recursiv se caracterizează prin proprietatea că se auto-apelează,
adică din interiorul lui se apelează pe el însuși. Din afara subprogramului facem un prim apel al acestuia, după care
subprogranul se auto-apelează de un anumit număr de ori: la fiecare nouă auto-apelare a subprogramului, se execută din nou secvența de
instrucțiuni ce reprezintă corpul său, eventual cu alte date, creându-se un așa-numit „lanț de auto-apeluri recursive”.
Putem spune că un subprogram recursiv are același efect ca și un ciclu: repetă execuția unei anumite
secvențe de instrucțiuni. Dar, la fel ca în cazul unui ciclu, este necesar ca repetarea să nu aibă loc la infinit. De aceea în corpul subprogramului trebuie să
existe cel puțin o testare a unei condiții de oprire, la îndeplinirea căreia se întrerupe lanțul de auto-apeluri.
|
int f(int n)
{
if (n==0) return 1;
else return n*f(n-1);
}
int main()
{ int n;
cout<<“n=“; cin>>n ;
cout << n <<“! = “<<f(n));
} | |
Funcţia factorial este scrisă după definiţia recursivă, respectiv
varianta iterativă:
|
| |
|
int f (int n)
{ int i,P=1;
for (i=1; i<= n; i++) P=P*i;
return P;
} | |
| |
| |
|
int n ;
// câte numere tipărim
void p(int i)
// procedura p cu parametrul i
{
if (i==n) cout<<n ; // rezolvarea directă (condiţia de STOP)
else {
cout<<i<<; //
Subproblema p(i): tipărim i
p(i+1); //
trecem la subproblema p(i+1)
}
}
int main()
{ cout<<“n=“; cin>>n; // citim valoarea lui n
p(1); &am
p;am
p;nbs
p; // apelul iniţial
} | |
Cum scriem un
subprogram recursiv ?
1. Trebuie să formulăm problema în termeni
recursivi
- stabilim
formula de recurenţă
- identificăm
soluţia în cazul rezolvării directe, dată de obicei sub forma condiţiilor iniţiale
- formulăm subproblemele de rezolvat în cazul în care
nu dispunem de o
formulă de recurenţă
- Scriem subprogramul recursiv:
- soluţia directă se
scrie sub forma condiţiei de oprire
- apelul recursiv
rezultă din formula de recurenţă
- la fiecare apel problema parţială trebuie rezolvată
complet