Sunteți pe pagina 1din 3

Recursivitatea

Un algoritm recursiv se caracterizeaza prin proprietatea ca se autoapeleaza, adica


din interiorul lui se apeleaza pe el insusi. Din afara algoritmului facem un prim apel al
acestuia, dupa care algoritmul se auto-apeleaza de un anumit numar de ori: la fiecare
noua auto-apelare a algoritmului, se executa din nou secventa de instructiuni ce
reprezinta corpul sau, eventual cu alte date, creandu-se un asa-numit “lant de auto-apeluri
recursive”.
Majoritatea algoritmilor repetitivi se pot implementa atat in varianta nerecursiva,
folosind cicluri, cat si in varianta recursiva. Varianta recursiva este recomandata in
special pentru problemele definite prin relatii de recurenta, care permit o formulare a
rezultatelor mult mai clara si mai concisa. Functionarea algoritmilor recursive este in
general mai greu de urmarit, si, in plus, acestia necesita un timp de executie mai lung si
un spatiu de memorie mai mare.
Extinzand definitia, com numi subprogram recursive, un subprogram care din
corpul lui se apeleaza pe el insusi. Dar orice subprogram recursive trebuie sa
indeplineasca doua cerinte:
▪ sa se poata executa cel putin o data fara a se auto-apela;
▪ toate auto-apelurile sa se produca astfel incat sa se tinda spre indeplinirea conditiei de
executie fara auto-apelare.

Siruri:

Un sir a1, a2,…,an,… este o succesiune de valori numite elementele sirului,


aranjate intr-o ordine bine definita. Fiecare element ocupa in cadrul sirului o pozitie
fixate, care se numeste rangul elementului.
Unele siruri pot fi definite cu ajutorul unor formule care exprima orice termen al
sirului, incepand cu un anumit rang, in functie de termenul precedent sau in functie de
termenii precedenti. O astfel de formula se numeste relatie de recurenta.

Sirul lui Fibonacci

Sirul lui Fibonacci este un sir de numere intregi (F1, F2,….Fn,…), definit recurrent
astfel: primii doi termini sunt egali cu 1, apoi, fiecare termen incepand cu al treilea, este
egal cu suma dintre precedentul si anteprecedentul sau este Fk-2.
De exemplu: F3=F2+F1=1+1=2 (pentru k=3), F4=F3+F2=2+1 (pentru k=4),
F5=F4+F3=3+2=5 (pentru k=5), etc.
Pentru o descriere completa scriem o relatie de recurenta care inglobeaza atat
formula de calcul, cat si valorile termenilor definiti separate:

1, pentru k = 1 si 2
Fk  
Fk-1 + Fk-2 , pentru k  3

Caracterul recursiv al algoritmului pentru determinarea termenilor sirului lui


Fibonacci este evident. Pentru a calcula un termen oarecare Fk, avem nevoie de termenii
precedenti Fk-1 si Fk-2. Dar aflarea termenilor Fk-1 si Fk-2 se poate face cu acelasi algoritm,
doar ca in loc de k avem k-1 respectiv k-2. Prin urmare, algoritmul care calculeaza
termenul Fk trebuie sa se auto-apeleze de doua ori, in scopul determinarii termenilor Fk-1
si Fk-2.

Factorialul unui numar

Factorialul unui numar natural k este k !  1  2  3...  (k  1)  k , care se mai poate


scrie k !  k  (k  1)  ...  3  2 1 . Observam insa ca factorialul lui 0 nu se poate calcula cu
relatia anterioara, acesta fiind un caz care trebuie tratat separate. Folosind faptul ca 0!=1,
obtinem relatia de recurenta completa:

1, pentru k = 0
k! 
 k  (k-1)! , pentru k > 0

Caracterul recursive consta in faptul ca din corpul algoritmului care calculeaza k!


se auto-apeleaza algoritmul pentru a calcula (k-1)! .

Sume cu n termini: suma primelor n numere naturale impare

De exemplu pentru n=5, sirul primelor cinci numere naturale impare este (1, 3, 5,
7, 9), iar suma acestora este S5  1  3  5  7  9 .
Observam ca se poate stabili o corespondenta intre rangul unui termen si valoarea
sa. Astfel: - primul termen, cu rangul 1, este 1, care se mai poate scrie 2 1  1 ;
- al doilea termen, cu rangul 2, este 3, care se mai poate scrie 2  2  1 ;
…………………………………………………………………………
- ultimul termen, cu rangul n=5, este 9, adica 2  5  1 , adica 2  n  1 .

Pe caz general, sirul primelor n numere naturale impare este (1, 3, 5, …,2n-1).
Notand termenii sirului cu a1 , a2 , ..., an , observam ca un termen oarecare ak (de rang k)
are valoarea 2  k  1 . Vom spune ca sirul de mai sus este definit prin formula termenului
general ak  2  k  1 .
Suma primelor n numere naturale este Sn  a1  a2  ...  an  1  3  5  ...  2n  1 .
Daca al n-lea termen, cel de rang n, este 2  n  1 , atunci al (n-1)-ulea termen este
2(n-1)-1, adica 2  n  3 . Astfel, S n  1  3  5  ...  (2  n  3)  (2  n  1) . Dar
1  3  5  ...  (2  n  3) reprezinta suma primelor n-1 numere naturale impare notata S n1
, deci S n  (2  n  1)  S n 1 . Pentru n=0, avem cazul particular S0  0. Obtinem astfel
relatia de recurenta completa:

0, pentru n  0
Sn = 
(2n  1) + S n 1 , pentru n  0
Si aceasta relatie genereaza un algoritm recursive: pentru a calcula suma S n ,
avem nevoie de suma S n1 .

Rolul stivei in executia subprogramelor recursive

Stiva este o succesiune ordonata de elemente, delimitate prin doua capete, in care
adaugarea si eliminarea elementelor se poate face pe la un singur capat, numit varful
stivei. In orice moment putem scoate din stiva doar elemental care a fost introdus ultimul,
motiv pentru care spunem ca stiva functioneaza dupa principiul LIFO (“Last In First
Out”).
Limbajul Pascal dispune de propria sa stiva, numita stiva interna, gestionata de
catre compilator, care ocupa o parte din memoria interna rezervata programului. Orice
subprogram foloseste aceasta stiva cand se executa.
In momentul in care un program (subprogram) P apeleaza un subprogram S, se
salveaza automat pe stiva interna adresa de revenire si contextual modulului appellant P.
Odata cu incheierea executiei modulului apelat S, se revine in P, restaurandu-se valorile
salvate pe stiva interna.
In cazul unui subprogram recursive, acest mechanism al stivei este de foarte mare
importanta: atunci cand se executa un lant de auto-apeluri recursive, la fiecare auto-apel
variabilele locale si parametrii subprogramului recursive se salveaza pe stiva, iar la
revenirea in ordine inverse din lant aceste valori se restaureaza de pe stiva.

S-ar putea să vă placă și