Sunteți pe pagina 1din 2

Recursivitate.

Principiul de execuţie

Stiva internă a limbajului. Rolul stivei în funcţionarea subprogramelor recursive

Stiva este o succesiune ordonată de elemente, delimitată prin două capete, în care adăugarea şi
eliminarea elementelor se poate face pe la un singur capăt, numit vârful stivei. O stivă care nu conţine nici un
element stivă vidă. În orice moment, putem scoate din stivă numai elementul care a fost introdus ultimul,
motiv pentru care vom spune că stiva funcţionează după principiul LIFO (Last In First Out – “Ultimul Intrat
Primul Ieşit”)
Limbajul C dispune de propria stivă internă, gestionată de către compilator. Ea ocupă o parte dein
memoria internă rezervată programului, iar adresele de început şi de sfârşit ale zonei de stivă sunt reţinute în
regiştrii microprocesorului.
Orice subprogram foloseşte această stivă.
În cazul subprogramelor recursive, stivă internă proprie a limbajului are o importanţă deosebită. La
fiecare nou autoapel al unui subprogram recursiv, se salvează pe stiva internă variabilele locale şi parametrii
transmişi prin valoare ai acestuia (un subprogram recursiv este şi modul apelant şi modul apelat în acelaşi
timp). Valorile salvate pe stivă nu numai că sunt restaurate în ordine inversă la revenirea din lanţul de apeluri
recursive, dar sunt şi efectiv folosite în formarea rezultatului final.

Reguli pentru scrierea subprogramelor recursive


A. Orice subprogram recursiv trebuie să se execute, cel puţin o dată, fără a se autoapela.
Condiţia de oprire se va scrie pentru valori extreme ale mulţimii valorilor de testat.
B. Autoapelurile trebuie să conducă spre situaţia (situaţiile ) în care subprogramul se execută
direct (fără autoapel).

Execuţia subprogramelor recursive


La activarea unui subprogram recursiv, se salvează în stiva procesorului (stack) :
- valorile parametrilor transmişi prin valoare şi adresa parametrilor transmişi prin referinţă
- valorile valriabilelor locale din subprogram
- adresa de revenire din subprogram.

Recursivitate sau iteraţie ?


Pentru orice algoritm recursiv există unul iterativ echivalent (care rezolvă aceeşi problemă) şi,
reciproc, pentru unul iterativ există unul recursiv echivalent.
Pentru care optăm?
Algoritmii recursivi, deoarece realizează la fiecare autoapel salvări pe stivă, necesită mai mult spaţiu
de memorie şi, implicit, timp de execuţie mai îndelungat.
Dacă numărul de autoapleluri este mare, spaţiul de memorie alocat stivei poate fi insuficient,
compilatorul transmite, în aceste situaţii, mesajul “stack overflow” (depăşire în stivă) şi programul nu poate
fi executat.
Să comparăm în continuare soluţia recursivă şi cea iterativă pentru o problemă nostimă:
Câte perechi de iepuri se pot obţine în n luni dintr-o singură pereche ştiind că:
- la momentul iniţial, iepurii din prima pereche sunt nou-născuţi;
- fiecare nouă pereche de iepuri devine fertilă după o lună;
- fiecare pereche produce o pereche de descendenţi în fiecare lună;
- nici un iepure nu moare.
Numărul perechilor de iepuri din fiecare lună este descris de şirul:
Luna 0 1 2 3 4 5 6 7 8 …….
Nr. perechi 1 1 2 3 5 8 13 21 34 ………
Notăm cu U(n) numărul perechilor din luna n. Atunci avem:
1, n=0
U(n) = 1, n=1
Acest şir este cunoscut ca şirul lui Fibonacci. U(n-1)+U(n-2), n>=2
Algoritmul recursiv decurge astfel: pentru calculul lui fib(n) sunt calculaţi fib(n-1) şi fib(n-2), ai căror
parametri sunt depuşi pe stivă. De exemplu, pentru a calcula fib(10) se calculează fib(9) şi fib(8); fib(9) ca
sumă de fib(8) şi fib(7), după care se calculează fib(8) încă o dată. Să ne imaginăm, pentru fib(500), de câte
ori se calculează fib(2) ! Deoarece metoda implică determinarea, cu salvările pe stivă aferente, a aceloraşi
valori în mod repetat, este de preferat, evident, varianta iterativă, mult mai naturală în această situaţie.

Tipuri de recursivitate

Există două tipuri de subprograme recursive :


a. subprograme direct recursive: - un subprogram Q în corpul căruia există cel puţin un autoapel (Q
apelează pe Q) se numeşte subprogram direct recursiv

b. subprograme indirect recursive: - două subprograme A şi B se numesc indirect recusrive dacă se


apelează reciproc (A apelează pe B şi B apelează A) .

Pentru a putea fi executat, orice subprogram (nerecursiv sau recursiv) trebuie să fie declarat înaintea
modulului apelant.

Situaţia ar fi fost una similară,dacă am fi scris procedurile în ordinea B,A. În acest caz trebuia
declarată anticipat procedura A.
g(x)+1 , x<=3

Exemplu : fie funcţiile f(x)= x2 , x>3


f,g :R  R , unde
5 , x<0
g(x)= f(x+1)+2x ,x>=0

Iată aici o situaţie aparte, în care funcţiile sunt recursive, însă, de data aceasta, una prin intermediul
celeilalte. Calculul, de exemplu, a lui f(2) decurge astfel:
f(2)=g(2)+1=(f(3)+2*2)+1=f(3)+5=(g(3)+1)+5=g(3)+6=(f(4)+2*3)+6=f(4)+12=42+12=16+12=28.

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