Sunteți pe pagina 1din 17

Derecursivare Derecursivare parcurgeri arbori binari scheme de recursie Memorarea intr-un tabel a rezultatelor subproblemelor

Functii recursive: conversie binara convert(12) procedure convert(x) 1.if (x != 0) 2.then convert(x/2) 3. print(x % 2) } 1100 110

convert(6)

convert(3)

11

0 1 3 3 3 6 3 12 3 x adr.retur stiva
Dorel Lucanu Algoritmica si programare

convert(1)

convert(0)
arborele apelurilor

Parcurgerea inordine a arborilor binari


Dat suprogramul: procedure inordine(v) 1: if v != NULL 2: then inordine(v->stg) 3: viziteaza(v) 4: inordine(v->drp) end sa se scrie un subprogram nerecursiv echivalent

Solutia
1. un program nerecursiv care simuleaza activitatea celui recursiv. 2. se rafineaza programul obtinut pana cand se obtine cea mai simpla structura Simularea se face cu ajutorul a doua stive o stiva pentru parametrii in care se vor memora referinte de noduri, notata spar; o stiva de protocol in care sunt memorate adresele de intoarcere in subprgram, notata sadr. Adresele sunt identificate prin intermediul etichetelor.

Solutia
fiecare apel recursiv este simulat de o secventa de instructiuni care realizeaza: salvarea starii curente a subprogramului introducerea valorilor (in cazul apelului prin valoare) sau adreselor (in cazul apelului prin referinta) parametrilor din instructiunea de apelare in stiva parametrilor; daca exista variabile locale, atunci se salveaza in stiva si valorile acestora introducerea adresei primei instructiuni ce urmeaza apelului in stiva adreselor de retur; actualizarea valorile parametrilor pentru noul apel recursiv; saltul la prima instructiune din subprogram.

Solutia
Primul apel recursiv push(spar, v) push(sadr, 3) v v->stg goto 1

procedure inordine(v) 1: if v != NULL 2: then inordine(v->stg) 3: viziteaza(v) 4: inordine(v->drp) end

Al doilea apel recursiv push(spar, v) push(sadr, 5) v v->drp goto 1

Solutia
Simularea terminarii executiei unui apel necesita urmatoarele operatii: Se restabileste starea subprogramului de dinaintea ultimului apel recursiv. Se reia calculul cu instructiunea data de varful stivei de protocol; aceasta adresa va fi eliminata din stiva.

Solutia
if not esteVida(spar) then v top(spar); pop(spar) adret top(sadr pop(sadr); switch (adret) case 3: goto 3 case 5: goto 5

Programul nerecursiv asamblat


procedure inordNerec1(t) // initializari spar stivaVida() sadr stivaVida() v t 1:if v != nil then // simuleaza primul apel recursiv 2: push(spar, v) push(sadr, 3) v v->stg; goto 1 else goto 5; 3:viziteaza(v) //simuleaza al doilea apel recursiv 4:push(spar,v) push(sadr,5) v v->drp goto 1

//simuleaza intoarcerea 5:if not esteVida(spar) then v Top(spar) pop(spar) adret top(sadr) pop(sadr) switch (adret) case 3: goto 3 case 5 goto 5 end

daca v->drp = null, este inutila introducerea in stiva daca v->=/= null, atunci poate fi rezolvat de 1:

Prima rafinare
procedure inordNerec2(t) spar stivaVida() sadr stivaVida() v t repeat while v != nil do push(spar, v) push(sadr, 3) v v->stg if not esteVida(spar) then v top(spar) pop(spar) adret top(sadr) pop(sadr) switch (adret) case 3 viziteaza(v) v v->drp until esteVida(spar) and (v = NULL) end

A doua rafinare
procedure inordNerec3(t) spar stivaVida() v t repeat while v != NULL do push(spar, v) v v->lstg if (not esteVida(spar)) then v top(spar) pop(spar) viziteaza(v) v v->ldrp until esteVida(spar) and (v = NULL) end

Memorarea intr-un tabel a rezultatelor subproblemelor

Rezolva probleme de la mic la mare si memoreaza rezultatele intr-un tabel!

Subprograme recursive: Fibonacci

function fibRec(n) if (n <= 1) then return n else return fibRec(n-1) + fibRec(n-2) end fibRec(5)
fibRec(4) fibRec(3) fibRec(2) fibRec(2) fibRec(1)

fibRec(3)

fibRec(2) fibRec(1) fibRec(1) fibRec(0) fibRec(1) fibRec(0) fibRec(1) fibRec(0)


Dorel Lucanu Algoritmica si programare

Fibonacci nerecursiv function fib(n) if (n<=1) return n f[0] 0 f[1] 1 for k 2 to n do f[k] f[k-2] + f[k-1] return f[n]; end

Dorel Lucanu

Algoritmica si programare

Fibonacci nerecursiv function fib(n) if (n<=1) return n // k = 1 fk_1 0 // fib[k-1] fk 1 // fib[k] for k 2 to n do fk_2 fk_1 fk_1 fk fk fk_2 + fk_1 return fk; end
Dorel Lucanu Algoritmica si programare

Numarul de expresii corect cu paranteze corect formate


((a b)+c)+(ab) (())() Pentru un numar natural n dat, notam cu P(n) numarul de expresii cu paranteze corect formate de lungime n.

Solutia
1. 2. 3. 4. Pornim de la definitia formala a expresiilor () E; daca e E, atunci (e) E; daca e1, e2, atunci e1e2 E ; E este cea mai mica multime care satisface conditiile de mai sus. P(n) = 0 pentru orice n impar. P(2) = 1 P(n) = P(n 2) + iI(n)P(i) P(n i) unde I(n) = {2, 4, . . . , n 2} Un subprogram recursiv care calculeaza P(n) are complexitatea timp exponentiala. Calculand valorile P(n) in ordinea P(2), P(4), . . . si memorandule intr-un tabel unidimensional obtinem un algoritm de complexitate timp O(n2).