![Page 1: Programarea Calculatoarelor Cursul 8: Recursivitateusers.utcluj.ro/~robert/pc/curs/C08.pdf · Recursivitate liniară •Este cea mai simplă formă de recursivitate •Apare atunci](https://reader030.vdocuments.pub/reader030/viewer/2022040218/5e05664f8f57ed398a280537/html5/thumbnails/1.jpg)
Programarea Calculatoarelor
Cursul 8: Recursivitate
Robert Varga
Universitatea Tehnică din Cluj-Napoca
Departamentul Calculatoare
![Page 2: Programarea Calculatoarelor Cursul 8: Recursivitateusers.utcluj.ro/~robert/pc/curs/C08.pdf · Recursivitate liniară •Este cea mai simplă formă de recursivitate •Apare atunci](https://reader030.vdocuments.pub/reader030/viewer/2022040218/5e05664f8f57ed398a280537/html5/thumbnails/2.jpg)
Recursivitatea
• Tehnică de programare puternică și de uz general în care o funcție se auto-apelează
• Stă la baza inducției matematice• O tehnică puternică care demonstrează multe teoreme matematice
• Ajută la descompunerea unei probleme de dimensiuni mari în subprobleme – tehnica Divide et Impera
• Rezolvarea subproblemelor și combinarea rezultatelor duc la soluția problemei
• Ajută la determinarea tuturor soluțiilor posibile ale unei probleme – tehnica Backtracking
• Permite scrierea programelor într-o manieră mult mai compactă și mai clară
22 noiembrie 2019 Programarea Calculatoarelor - R. Varga 2
![Page 3: Programarea Calculatoarelor Cursul 8: Recursivitateusers.utcluj.ro/~robert/pc/curs/C08.pdf · Recursivitate liniară •Este cea mai simplă formă de recursivitate •Apare atunci](https://reader030.vdocuments.pub/reader030/viewer/2022040218/5e05664f8f57ed398a280537/html5/thumbnails/3.jpg)
Recursivitatea
• O funcție recursivă se poate auto-apela• Direct – funcția conține un apel al ei însăși
• Indirect – funcția conține un apel al altei funcții, iar aceasta din urmă conține la rândul ei un apel către prima funcție
• La fiecare apel recursiv se stochează la locații separate pe stivă
• Valorile variabilelor locale automate pentru apelul respectiv
• Valorile parametrilor formali pentru apelul respectiv
• Adresa de întoarcere din apelul respectiv
• De-a lungul apelurilor recursive sunt stocate pe heap și își păstrează locația
• Variabilele statice
• Variabilele globale
22 noiembrie 2019 Programarea Calculatoarelor - R. Varga 3
![Page 4: Programarea Calculatoarelor Cursul 8: Recursivitateusers.utcluj.ro/~robert/pc/curs/C08.pdf · Recursivitate liniară •Este cea mai simplă formă de recursivitate •Apare atunci](https://reader030.vdocuments.pub/reader030/viewer/2022040218/5e05664f8f57ed398a280537/html5/thumbnails/4.jpg)
Terminarea recursivității
• O funcție recursivă trebuie să aibă în construcția ei o condiție de terminare
• Altfel apelul recursiv poate să ducă la o buclă infinită (asemănătoare structurilor repetitive în care condiția de continuare este întotdeauna adevărată și care iterează la nesfârșit)!
• Adâncimea recursivității trebuie să nu fie una foarte mare
• La fiecare apel recursiv se memorează pe stivă• Parametrii funcției
• Variabilele locale automate
• Adresa de revenire din apelul funcției
• Aceasta variază în funcție de numărul de octeți conținuți în parametrii și variabilele locale automate
• În cazul depășirii dimensiunii maxime a stivei, programul se termină subit în urma unei erori – stack overflow
22 noiembrie 2019 Programarea Calculatoarelor - R. Varga 4
![Page 5: Programarea Calculatoarelor Cursul 8: Recursivitateusers.utcluj.ro/~robert/pc/curs/C08.pdf · Recursivitate liniară •Este cea mai simplă formă de recursivitate •Apare atunci](https://reader030.vdocuments.pub/reader030/viewer/2022040218/5e05664f8f57ed398a280537/html5/thumbnails/5.jpg)
Recursivitate liniară
• Este cea mai simplă formă de recursivitate
• Apare atunci când o acțiune are o structură simplă repetitivă care constă într-un proces urmat de repetarea acțiunii respective
• Poate fi transformată în iterații nerecursive prin plasarea procesului într-o structură repetitivă (ex.: for, while)
• Condiția de terminare a recursivității este utilizată pentru a termina iterarea în cadrul structurii repetitive
• Exemple• Calculul sumei primelor n numere naturale
• Inversarea unui șir de valori
• Calculul minimului unui șir de valori
22 noiembrie 2019 Programarea Calculatoarelor - R. Varga 5
![Page 6: Programarea Calculatoarelor Cursul 8: Recursivitateusers.utcluj.ro/~robert/pc/curs/C08.pdf · Recursivitate liniară •Este cea mai simplă formă de recursivitate •Apare atunci](https://reader030.vdocuments.pub/reader030/viewer/2022040218/5e05664f8f57ed398a280537/html5/thumbnails/6.jpg)
Exemplu
• Suma a primelor n numere naturale
𝑠𝑢𝑚 𝑛 = 0 dacă 𝑛 = 0
𝑛 + 𝑠𝑢𝑚(𝑛 − 1) dacă 𝑛 > 0
• Se identifică cazul special (n=0) în care funcția sum nu se apelează recursiv
• În cazul apelului recursiv se observă că parametrul nscade cu 1 la fiecare apel => se îndreaptă către cazul special (condiția de terminare) dacă n este un număr natural
22 noiembrie 2019 Programarea Calculatoarelor - R. Varga 6
![Page 7: Programarea Calculatoarelor Cursul 8: Recursivitateusers.utcluj.ro/~robert/pc/curs/C08.pdf · Recursivitate liniară •Este cea mai simplă formă de recursivitate •Apare atunci](https://reader030.vdocuments.pub/reader030/viewer/2022040218/5e05664f8f57ed398a280537/html5/thumbnails/7.jpg)
Exemplu
#include <stdio.h>
int sum(int n){
printf("Apel recursiv cu n=%d\n", n);
int rez = 0;
if (n<=0)
rez = 0;
else
rez = n + sum(n-1); /* &2=adresa de intoarcere dupa apelul lui sum(n-1) */
printf("Iesirea din apelul recursiv cu n=%d\n", n);
return rez;
}
int main() {
int n;
printf("n=");
scanf("%d", &n);
int rez = sum(n);
for(int i=1; i<n; i++)
printf("%d + ", i);
printf("%d = %d", n, rez); /* &1=adresa de intoarcere dupa evaluarea lui sum(n) */
return 0;
}22 noiembrie 2019 Programarea Calculatoarelor - R. Varga 7
![Page 8: Programarea Calculatoarelor Cursul 8: Recursivitateusers.utcluj.ro/~robert/pc/curs/C08.pdf · Recursivitate liniară •Este cea mai simplă formă de recursivitate •Apare atunci](https://reader030.vdocuments.pub/reader030/viewer/2022040218/5e05664f8f57ed398a280537/html5/thumbnails/8.jpg)
Exemplu
Intrare și rezultate afișate de program:n=3
Apel recursiv cu n=3
Apel recursiv cu n=2
Apel recursiv cu n=1
Apel recursiv cu n=0
Iesirea din apelul recursiv cu n=0
Iesirea din apelul recursiv cu n=1
Iesirea din apelul recursiv cu n=2
Iesirea din apelul recursiv cu n=3
1 + 2 + 3 = 6
22 noiembrie 2019 Programarea Calculatoarelor - R. Varga 8
![Page 9: Programarea Calculatoarelor Cursul 8: Recursivitateusers.utcluj.ro/~robert/pc/curs/C08.pdf · Recursivitate liniară •Este cea mai simplă formă de recursivitate •Apare atunci](https://reader030.vdocuments.pub/reader030/viewer/2022040218/5e05664f8f57ed398a280537/html5/thumbnails/9.jpg)
Exemplu
• Evoluția stivei de apeluri:a. Imediat după intrarea în
apelul lui sum(3)
b. Imediat după intrarea în apelul recursiv al lui sum(2)
c. Imediat după intrarea în apelul recursiv al lui sum(1)
d. Imediat după intrarea în apelul recursiv al lui sum(0)
e. Imediat după ieșirea din apelul recursiv (pentru n=0)
f. Imediat după ieșirea din apelul recursiv (pentru n=1)
g. Imediat după ieșirea din apelul recursiv (pentru n=2)
h. Imediat după ieșirea din apelul recursiv (pentru n=3)în funcția main()
22 noiembrie 2019 Programarea Calculatoarelor - R. Varga 9
&1n=3
&2n=2&1n=3
&2n=2&1n=3
&2n=1&2n=2&1n=3
&2n=0&2n=1&2n=2&1n=3
&2n=1&2n=2&1n=3
&2n=2&1n=3
&1n=3
a. b. c. d.
e. f. g. h.
![Page 10: Programarea Calculatoarelor Cursul 8: Recursivitateusers.utcluj.ro/~robert/pc/curs/C08.pdf · Recursivitate liniară •Este cea mai simplă formă de recursivitate •Apare atunci](https://reader030.vdocuments.pub/reader030/viewer/2022040218/5e05664f8f57ed398a280537/html5/thumbnails/10.jpg)
Exemplu – însumarea elementelordintr-un tablou
int sum_last(int n, int* a){
if (n==1)
return a[n-1];
else
return a[n-1] + sum_last(n-1, a);
}
int sum_first(int n, int* a){
if (n==1)
return a[0];
else
return a[0] + sum_first(n-1, a+1);
}
int sum_mid(int from, int to, int* a){
if (from == to)
return a[from];
else{
int m = (from+to)/2;
return sum_mid(from, m, a) + sum_mid(m+1, to, a);
}
}
22 noiembrie 2019 Programarea Calculatoarelor - R. Varga 10
![Page 11: Programarea Calculatoarelor Cursul 8: Recursivitateusers.utcluj.ro/~robert/pc/curs/C08.pdf · Recursivitate liniară •Este cea mai simplă formă de recursivitate •Apare atunci](https://reader030.vdocuments.pub/reader030/viewer/2022040218/5e05664f8f57ed398a280537/html5/thumbnails/11.jpg)
Exemplu – însumarea elementelordintr-un tablou
#include <stdio.h>
int sum_last(int n, int* a);int sum_first(int n, int* a);int sum_mid(int from, int to, int* a);
int main() {int a[] = {1, 2, 3, 4};int n = sizeof(a)/sizeof(a[0]);printf("last %d\n", sum_last(n, a));printf("first %d\n", sum_first(n, a));printf("mid %d\n", sum_mid(0, n-1, a));return 0;
}
22 noiembrie 2019 Programarea Calculatoarelor - R. Varga 11
![Page 12: Programarea Calculatoarelor Cursul 8: Recursivitateusers.utcluj.ro/~robert/pc/curs/C08.pdf · Recursivitate liniară •Este cea mai simplă formă de recursivitate •Apare atunci](https://reader030.vdocuments.pub/reader030/viewer/2022040218/5e05664f8f57ed398a280537/html5/thumbnails/12.jpg)
Exemple de funcții recursive
• Șirul lui Fibonacci
𝐹 𝑛 = 0 𝑑𝑎𝑐ă 𝑛 = 01 𝑑𝑎𝑐ă 𝑛 = 1
𝐹 𝑛 − 1 + 𝐹(𝑛 − 2) 𝑑𝑎𝑐ă 𝑛 > 1
• Numărul de compoziții ale unui număr natural pozitiv• Numărul de moduri de a scrie n ca o sumă de numere naturale
pozitive
• Exemplu pentru numărul 4 sunt 8 compoziții:1+1+1+1= 1+1+2 = 1+2+1 = 2+1+1 = 1+3 = 2+2 = 3+1 = 4
22 noiembrie 2019 Programarea Calculatoarelor - R. Varga 12
![Page 13: Programarea Calculatoarelor Cursul 8: Recursivitateusers.utcluj.ro/~robert/pc/curs/C08.pdf · Recursivitate liniară •Este cea mai simplă formă de recursivitate •Apare atunci](https://reader030.vdocuments.pub/reader030/viewer/2022040218/5e05664f8f57ed398a280537/html5/thumbnails/13.jpg)
Exemplu – Șirul lui Fibonacci
#include <stdio.h>
#include <stdlib.h>
int fib(int n)
{
if (n==0)
return 0;
if (n==1)
return 1;
return fib(n-1)+fib(n-2);
}
int main()
{
printf("%d\n",fib(20)); //6765
printf("%d\n",fib(42)); //Timp de executie ridicat!!! – recalculam multe valori
return 0;
}
22 noiembrie 2019 Programarea Calculatoarelor - R. Varga 13
![Page 14: Programarea Calculatoarelor Cursul 8: Recursivitateusers.utcluj.ro/~robert/pc/curs/C08.pdf · Recursivitate liniară •Este cea mai simplă formă de recursivitate •Apare atunci](https://reader030.vdocuments.pub/reader030/viewer/2022040218/5e05664f8f57ed398a280537/html5/thumbnails/14.jpg)
Greșeli des întâlnite
• Nu există condiție de terminare:void afisare_cifre(int n) {
afisare_cifre(n / 10);
printf("%d\n", (n % 10));
}
• Există condiție de terminare, dar apelul recursiv nu modifică valoarea parametrului:
void afisare_cifre(int n) {
if (n < 10)
printf("%d\n", n);
else
{
afisare_cifre(n);
printf("%d\n", (n % 10));
}
}
22 noiembrie 2019 Programarea Calculatoarelor - R. Varga 14
![Page 15: Programarea Calculatoarelor Cursul 8: Recursivitateusers.utcluj.ro/~robert/pc/curs/C08.pdf · Recursivitate liniară •Este cea mai simplă formă de recursivitate •Apare atunci](https://reader030.vdocuments.pub/reader030/viewer/2022040218/5e05664f8f57ed398a280537/html5/thumbnails/15.jpg)
Greșeli des întâlnite –recursivitate adâncă
#include <stdio.h>
int sum(int n){int rez = 0;if (n<=0)
rez = 0;else
rez = n + sum(n-1);return rez;
}
int main() {sum(1e7);return 0;
}
22 noiembrie 2019 Programarea Calculatoarelor - R. Varga 15
![Page 16: Programarea Calculatoarelor Cursul 8: Recursivitateusers.utcluj.ro/~robert/pc/curs/C08.pdf · Recursivitate liniară •Este cea mai simplă formă de recursivitate •Apare atunci](https://reader030.vdocuments.pub/reader030/viewer/2022040218/5e05664f8f57ed398a280537/html5/thumbnails/16.jpg)
Recursivitatea – important !
• Pentru a evita ciclul infinit scrieți un caz special în care funcția să nu se apeleze recursiv
• Atenție la funcțiile care se pot apela prin recursivitate indirectă
• Recursivitatea trebuie gândită bine – altfel se pot scrie programe total ineficiente
• Recursivitatea este o alternativă pentru structurile repetitive for si while utilizate în calcule ce necesită iterații multiple
• Funcțiile recursive sunt foarte utile când structurile de date (ex. arbori binari de căutare) sau paradigma de programare (ex. divide et impera) sunt recursive prin definiție
22 noiembrie 2019 Programarea Calculatoarelor - R. Varga 16
![Page 17: Programarea Calculatoarelor Cursul 8: Recursivitateusers.utcluj.ro/~robert/pc/curs/C08.pdf · Recursivitate liniară •Este cea mai simplă formă de recursivitate •Apare atunci](https://reader030.vdocuments.pub/reader030/viewer/2022040218/5e05664f8f57ed398a280537/html5/thumbnails/17.jpg)
Recursivitatea – important !
• O funcție recursivă ar trebui să aibă următoarele trei proprietăți
• Nu se auto-apelează la infinit• Se va identifica cazul special (sau condiția de terminare) în care funcția nu se
auto-apelează
• Se va asigura faptul că succesiunea de apeluri recursive va conduce către acest caz special
• Pot să existe mai multe astfel de cazuri speciale
• Fiecare caz special de oprire• Trebuie să returneze valoarea corectă pentru acel caz (în cazul funcțiilor care
returnează o valoare)
• Trebuie să execute acțiunile corecte pentru acel caz (în cazul funcțiilor care nu returnează nicio valoare)
• Pentru cazurile care necesită apeluri recursive, dacă apelul recursiv se execută corect (sau returnează o valoare corectă) atunci acțiunea finală este corectă (sau calculul final este corect)
22 noiembrie 2019 Programarea Calculatoarelor - R. Varga 17
![Page 18: Programarea Calculatoarelor Cursul 8: Recursivitateusers.utcluj.ro/~robert/pc/curs/C08.pdf · Recursivitate liniară •Este cea mai simplă formă de recursivitate •Apare atunci](https://reader030.vdocuments.pub/reader030/viewer/2022040218/5e05664f8f57ed398a280537/html5/thumbnails/18.jpg)
Recursivitate – important !
• Nu vă gândiți în mod recursiv dacă• Folosiți variabile globale
• Folosiți variabile statice
• Transmiteți rezultate parțiale la autoapel• Este în regulă dacă vrem să construim răspunsul
• Numărul de parametrii la funcție nu este minimal
22 noiembrie 2019 Programarea Calculatoarelor - R. Varga 18
![Page 19: Programarea Calculatoarelor Cursul 8: Recursivitateusers.utcluj.ro/~robert/pc/curs/C08.pdf · Recursivitate liniară •Este cea mai simplă formă de recursivitate •Apare atunci](https://reader030.vdocuments.pub/reader030/viewer/2022040218/5e05664f8f57ed398a280537/html5/thumbnails/19.jpg)
Etapele rezolvării unei probleme folosind recursivitate
• Rezolvarea pentru un caz simplu (de bază)
• Rezolvarea pentru cazuri mici – opțional, dar recomandat
• Stabilirea relației de recurență• Studiem cum putem să reducem problema la o subproblemă
• Observăm ce se întamplă: la primul pas, la ultimul pas sau la mijloc
• Cum putem să combinăm rezultatele de la subprobleme pentru a da răspunsul
• Implementare recursivă• Cu tehnica de memoizare (memorare)
• Implementare iterativă
• Formulă generală fără recursivitate
22 noiembrie 2019 Programarea Calculatoarelor - R. Varga 19
![Page 20: Programarea Calculatoarelor Cursul 8: Recursivitateusers.utcluj.ro/~robert/pc/curs/C08.pdf · Recursivitate liniară •Este cea mai simplă formă de recursivitate •Apare atunci](https://reader030.vdocuments.pub/reader030/viewer/2022040218/5e05664f8f57ed398a280537/html5/thumbnails/20.jpg)
Triangularizări n-gon
• Calculați numărul de moduri de a triangula un poligon convex cu n vârfuri, 3<=n<35
• În câte moduri se poate împărți în triunghiuri
• Împărțirea se face dealungul diagonalelor
• Diagonalele nu se intersectează
• Exemple de triangulări:• n = 4 n = 6
• Fie T(n) numărul de moduri
22 noiembrie 2019 Programarea Calculatoarelor - R. Varga 20
![Page 21: Programarea Calculatoarelor Cursul 8: Recursivitateusers.utcluj.ro/~robert/pc/curs/C08.pdf · Recursivitate liniară •Este cea mai simplă formă de recursivitate •Apare atunci](https://reader030.vdocuments.pub/reader030/viewer/2022040218/5e05664f8f57ed398a280537/html5/thumbnails/21.jpg)
Triangularizări n-gon
• Rezolvarea pentru un caz simplu • Pentru n=3
• Un triunghi se poate triangula într-un singur mod
T(3) = 1
22 noiembrie 2019 Programarea Calculatoarelor - R. Varga 21
![Page 22: Programarea Calculatoarelor Cursul 8: Recursivitateusers.utcluj.ro/~robert/pc/curs/C08.pdf · Recursivitate liniară •Este cea mai simplă formă de recursivitate •Apare atunci](https://reader030.vdocuments.pub/reader030/viewer/2022040218/5e05664f8f57ed398a280537/html5/thumbnails/22.jpg)
Triangularizări n-gon
• Rezolvarea pentru cazuri mici• Pentru n=4, avem T(4) = 2
• Pentru n=5, avem T(5) = 5
22 noiembrie 2019 Programarea Calculatoarelor - R. Varga 22
![Page 23: Programarea Calculatoarelor Cursul 8: Recursivitateusers.utcluj.ro/~robert/pc/curs/C08.pdf · Recursivitate liniară •Este cea mai simplă formă de recursivitate •Apare atunci](https://reader030.vdocuments.pub/reader030/viewer/2022040218/5e05664f8f57ed398a280537/html5/thumbnails/23.jpg)
Triangularizări n-gon
• Rezolvarea pentru cazuri mici• Pentru n=6, avem T(6) = 14
22 noiembrie 2019 Programarea Calculatoarelor - R. Varga 23
![Page 24: Programarea Calculatoarelor Cursul 8: Recursivitateusers.utcluj.ro/~robert/pc/curs/C08.pdf · Recursivitate liniară •Este cea mai simplă formă de recursivitate •Apare atunci](https://reader030.vdocuments.pub/reader030/viewer/2022040218/5e05664f8f57ed398a280537/html5/thumbnails/24.jpg)
Triangularizări n-gon
• Stabilirea relației de recurență• Numerotăm vârfurile și studiem ce se întâmplă cu vârful 1
22 noiembrie 2019 Programarea Calculatoarelor - R. Varga 24
1 2
3n
n-1 ...
i
![Page 25: Programarea Calculatoarelor Cursul 8: Recursivitateusers.utcluj.ro/~robert/pc/curs/C08.pdf · Recursivitate liniară •Este cea mai simplă formă de recursivitate •Apare atunci](https://reader030.vdocuments.pub/reader030/viewer/2022040218/5e05664f8f57ed398a280537/html5/thumbnails/25.jpg)
Triangularizări n-gon
• Stabilirea relației de recurență• Vârful 1 poate fi conectat la unul din vârfurile 3, 4, ..., n-1
22 noiembrie 2019 Programarea Calculatoarelor - R. Varga 25
1 2
3n
n-1 ...
i
![Page 26: Programarea Calculatoarelor Cursul 8: Recursivitateusers.utcluj.ro/~robert/pc/curs/C08.pdf · Recursivitate liniară •Este cea mai simplă formă de recursivitate •Apare atunci](https://reader030.vdocuments.pub/reader030/viewer/2022040218/5e05664f8f57ed398a280537/html5/thumbnails/26.jpg)
Triangularizări n-gon
• Stabilirea relației de recurență• Dacă conectăm la vârful i
• Poligonul se împarte în două părți care se pot triangula independent
22 noiembrie 2019 Programarea Calculatoarelor - R. Varga 26
1 2
3n
n-1 ...
i
poligon cu i vârfuri
poligon cu n-i+2
vârfuri
![Page 27: Programarea Calculatoarelor Cursul 8: Recursivitateusers.utcluj.ro/~robert/pc/curs/C08.pdf · Recursivitate liniară •Este cea mai simplă formă de recursivitate •Apare atunci](https://reader030.vdocuments.pub/reader030/viewer/2022040218/5e05664f8f57ed398a280537/html5/thumbnails/27.jpg)
Triangularizări n-gon
• Stabilirea relației de recurență• Vârful 1 nu este conectat• Trebuie să existe triunghiul (n,1,2) și rămâne un (n-1)-gon
22 noiembrie 2019 Programarea Calculatoarelor - R. Varga 27
1 2
3n
n-1 ...
i
![Page 28: Programarea Calculatoarelor Cursul 8: Recursivitateusers.utcluj.ro/~robert/pc/curs/C08.pdf · Recursivitate liniară •Este cea mai simplă formă de recursivitate •Apare atunci](https://reader030.vdocuments.pub/reader030/viewer/2022040218/5e05664f8f57ed398a280537/html5/thumbnails/28.jpg)
Triangularizări n-gon
• Stabilirea relației de recurență• Dacă conectăm vârful 1 la vârful i avem T(i)T(n-i+2) modalități
• i poate fi 3, 4, ... n-1
• Dacă nu conectăm vârful 1 la nimic avem T(n-1) modalități
• Rezultă formula de recurență
𝑇 𝑛 =
𝑖=3
𝑛−1
𝑇 𝑖 𝑇 𝑛 − 𝑖 + 2 + 𝑇(𝑛 − 1)
• Dar unele cazuri se suprapun
• Conectăm vârful 1 cu i apoi cu j
• Conectăm vârful 1 cu j apoi cu i
• Recurență greșită!
22 noiembrie 2019 Programarea Calculatoarelor - R. Varga 28
![Page 29: Programarea Calculatoarelor Cursul 8: Recursivitateusers.utcluj.ro/~robert/pc/curs/C08.pdf · Recursivitate liniară •Este cea mai simplă formă de recursivitate •Apare atunci](https://reader030.vdocuments.pub/reader030/viewer/2022040218/5e05664f8f57ed398a280537/html5/thumbnails/29.jpg)
Triangularizări n-gon
• Stabilirea relației de recurență• Numerotăm vârfurile și studiem ce se întâmplă cu muchia 1-2
22 noiembrie 2019 Programarea Calculatoarelor - R. Varga 29
1 2
3n
n-1 ...
i
![Page 30: Programarea Calculatoarelor Cursul 8: Recursivitateusers.utcluj.ro/~robert/pc/curs/C08.pdf · Recursivitate liniară •Este cea mai simplă formă de recursivitate •Apare atunci](https://reader030.vdocuments.pub/reader030/viewer/2022040218/5e05664f8f57ed398a280537/html5/thumbnails/30.jpg)
Triangularizări n-gon
• Stabilirea relației de recurență• Muchia 1-2 poate forma un triunghi cu orice vârf 4, 5, ..., n-1
22 noiembrie 2019 Programarea Calculatoarelor - R. Varga 30
1 2
3n
n-1 ...
i
![Page 31: Programarea Calculatoarelor Cursul 8: Recursivitateusers.utcluj.ro/~robert/pc/curs/C08.pdf · Recursivitate liniară •Este cea mai simplă formă de recursivitate •Apare atunci](https://reader030.vdocuments.pub/reader030/viewer/2022040218/5e05664f8f57ed398a280537/html5/thumbnails/31.jpg)
Triangularizări n-gon
• Stabilirea relației de recurență• Mai rămân două părți care se pot triangula independent
22 noiembrie 2019 Programarea Calculatoarelor - R. Varga 31
1 2
3n
n-1 ...
i
poligon cu i-1
vârfuri
poligon cu n-i+2
vârfuri
![Page 32: Programarea Calculatoarelor Cursul 8: Recursivitateusers.utcluj.ro/~robert/pc/curs/C08.pdf · Recursivitate liniară •Este cea mai simplă formă de recursivitate •Apare atunci](https://reader030.vdocuments.pub/reader030/viewer/2022040218/5e05664f8f57ed398a280537/html5/thumbnails/32.jpg)
Triangularizări n-gon
• Stabilirea relației de recurență• Muchia 1-2 poate forma un triunghi cu vârful 3 sau cu n• Rămâne un (n-1)-gon de triangulat
22 noiembrie 2019 Programarea Calculatoarelor - R. Varga 32
1 2
3n
n-1 ...
i
![Page 33: Programarea Calculatoarelor Cursul 8: Recursivitateusers.utcluj.ro/~robert/pc/curs/C08.pdf · Recursivitate liniară •Este cea mai simplă formă de recursivitate •Apare atunci](https://reader030.vdocuments.pub/reader030/viewer/2022040218/5e05664f8f57ed398a280537/html5/thumbnails/33.jpg)
Triangularizări n-gon
• Stabilirea relației de recurență• Dacă conectăm 1-2 la i avem T(i-1)T(n-i+2) modalități
• i poate fi 4, 5, ... n-1
• Dacă conectăm 1-2 la 3 sau cu n avem câte T(n-1) modalități• Rezultă formula de recurență
𝑇 𝑛 =
𝑖=4
𝑛−1
𝑇 𝑖 − 1 𝑇 𝑛 − 𝑖 + 2 + 2𝑇(𝑛 − 1)
• Dacă adoptăm T(2) = 1 atunci
𝑇 𝑛 =
𝑖=3
𝑛
𝑇 𝑖 − 1 𝑇 𝑛 − 𝑖 + 2
• Cazurile nu se suprapun• Recurență corectă!
22 noiembrie 2019 Programarea Calculatoarelor - R. Varga 33
![Page 34: Programarea Calculatoarelor Cursul 8: Recursivitateusers.utcluj.ro/~robert/pc/curs/C08.pdf · Recursivitate liniară •Este cea mai simplă formă de recursivitate •Apare atunci](https://reader030.vdocuments.pub/reader030/viewer/2022040218/5e05664f8f57ed398a280537/html5/thumbnails/34.jpg)
Triangularizări n-gon
• Implementare recursivă
long long triangulari(int n){
if (n<=3)
return 1;
long long rez = 0;
for(int i=3; i<=n; i++)
rez += triangulari(i-1)*triangulari(n-i+2);
return rez;
}
• triangulari(20) = 477638700 sub o secundă
• triangulari(30) ?
22 noiembrie 2019 Programarea Calculatoarelor - R. Varga 34
![Page 35: Programarea Calculatoarelor Cursul 8: Recursivitateusers.utcluj.ro/~robert/pc/curs/C08.pdf · Recursivitate liniară •Este cea mai simplă formă de recursivitate •Apare atunci](https://reader030.vdocuments.pub/reader030/viewer/2022040218/5e05664f8f57ed398a280537/html5/thumbnails/35.jpg)
Triangularizări n-gon
• Implementare recursivă – cu memoizare
long long T[50] = {[2] = 1, [3] = 1};
long long triangulari(int n){
if (T[n]>0)
return T[n];
long long rez = 0;
for(int i=3; i<=n; i++)
rez += triangulari(i-1)*triangulari(n-i+2);
T[n] = rez;
return rez;
}
• triangulari(20) = 477638700
• triangulari(30) = 263747951750360 câteva millisecunde
22 noiembrie 2019 Programarea Calculatoarelor - R. Varga 35
![Page 36: Programarea Calculatoarelor Cursul 8: Recursivitateusers.utcluj.ro/~robert/pc/curs/C08.pdf · Recursivitate liniară •Este cea mai simplă formă de recursivitate •Apare atunci](https://reader030.vdocuments.pub/reader030/viewer/2022040218/5e05664f8f57ed398a280537/html5/thumbnails/36.jpg)
Triangularizări n-gon
• Implementare iterativă
long long triangulari_iter(int n){
long long T[50] = {[2] = 1, [3] = 1};
for(int k=4; k<=n; k++){
for(int i=3; i<=k; i++)
T[k] += T[i-1]*T[k-i+2];
}
return T[n];
}
• Formulă directă – numere Catalan• T(n) = C(n-2), unde
𝐶 𝑛 =1
𝑛 + 12𝑛𝑛
22 noiembrie 2019 Programarea Calculatoarelor - R. Varga 36