Algoritmi recursivi Structuri de date i algoritmi 1

  • Slides: 15
Download presentation
Algoritmi recursivi Structuri de date şi algoritmi 1 -laborators. l. dr. ing. Ciprian-Bogdan Chirilă

Algoritmi recursivi Structuri de date şi algoritmi 1 -laborators. l. dr. ing. Ciprian-Bogdan Chirilă Universitatea Politehnica Timişoara 2014

Cuprins n n n Ce este recursivitatea ? Verificarea şi simularea programelor recursive Tipuri

Cuprins n n n Ce este recursivitatea ? Verificarea şi simularea programelor recursive Tipuri de algoritmi recursivi n n Algoritmi de traversare a unei structuri Algoritmi care implementează definiţii recursive n factorial, Euclid, ridicarea la putere Algoritmi de divizare n quicksort, căutarea binară Algoritmi cu revenire (backtracking) n săritura calului, problema celor 8 regine n aranjamente (cu/fără repetiţie), combinări “de m luate câte n”

Ce este recursivitatea ? n n Recursivitatea presupune execuţia repetată a unui modul; Pe

Ce este recursivitatea ? n n Recursivitatea presupune execuţia repetată a unui modul; Pe parcursul său se verifică o condiţie a cărei nesatisfacere implică reluarea execuţiei modulului de la începutul său; Directă - un modul P conţine o referinţă la el însuşi; Indirectă – un modul P conţine o referinţă la un modul Q ce include o referinţă la P;

Verificarea şi simularea programelor recursive n n Demonstraţie formală sau testând toate cazurile posibile

Verificarea şi simularea programelor recursive n n Demonstraţie formală sau testând toate cazurile posibile Se verifică cazurile particulare (condiţia de terminare a apelurilor recursive) Se verifică formal procedura recursivă pentru restul cazurilor Verificarea se face prin inducţie

Exemplu - factorial int factorial(int n) { if(n==0) { // verificare pentru n=0 n!=1

Exemplu - factorial int factorial(int n) { if(n==0) { // verificare pentru n=0 n!=1 return 1; } else { // verificare pentru n>0 n!=n*(n-1)! return n*factorial(n-1); } }

Algoritmi care implementează definiţii recursive Exemplu – algoritmul lui Euclid int cmmdc(int x, int

Algoritmi care implementează definiţii recursive Exemplu – algoritmul lui Euclid int cmmdc(int x, int y) { if(x<y) { int aux=x; x=y; y=aux; } if(y!=0) { return cmmdc(y, x%y); } return x; }

Algoritmi de traversare a unei structuri void traversare(tip_element) /* apelul initial al procedurii se

Algoritmi de traversare a unei structuri void traversare(tip_element) /* apelul initial al procedurii se face cu primelement al structurii */ { prelucrare(element); if element != ultimul_din_structura traversare(element_urmator); }

Algoritmi de divizare void rezolva(problema x) { if /* x e divizibil in subprobleme

Algoritmi de divizare void rezolva(problema x) { if /* x e divizibil in subprobleme */ { /* divide pe x in parti x 1, . . . , xk */ rezolva(x 1); /*…*/ rezolva(xk); /* combina solutiile partiale intr-o solutie pentru x */ } else /* rezolva pe x direct */ }

Algoritmi cu revenire (backtracking) n n n x=(x 1, x 2, . . .

Algoritmi cu revenire (backtracking) n n n x=(x 1, x 2, . . . xn) € S=S 1 x S 2 x. . . x Sn S – spaţiul soluţiilor posibile condiţii interne – relaţii între componentele vectorului x

Algoritmi cu revenire (backtracking) void backtracking(int i) //gaseste valoarea lui xi int posibilitate; //pentru

Algoritmi cu revenire (backtracking) void backtracking(int i) //gaseste valoarea lui xi int posibilitate; //pentru toate valorile posibile ale lui xi { for(posibilitate=1; posibilitate<=M; posibilitate++) { if(acceptabila) { inregisteaza_posibilitatea; if(i < n)backtracking(i+1) else afiseaza_solutia; sterge_inregistrarea } } }

Exemplu - aranjamente int valid(int p) { if(p>0) { return tab[p]!=tab[p-1]; } return 1;

Exemplu - aranjamente int valid(int p) { if(p>0) { return tab[p]!=tab[p-1]; } return 1; } void aranjamente(int k) { int i; if(k<n) { for(i=1; i<=m; i++) { tab[k]=i; if(valid(k))aranjamente(k+1); } } else print(); }

Exemplu – combinări int valid(int p) { if(p>0) { return tab[p]>tab[p-1]; } return 1;

Exemplu – combinări int valid(int p) { if(p>0) { return tab[p]>tab[p-1]; } return 1; } void aranjamente(int k) { int i; if(k<n) { for(i=1; i<=m; i++) { tab[k]=i; if(valid(k))aranjamente(k+1); } } else print(); }

Exemplu – 8 regine (1) void dame(int k) {int i; if(k<n) { for(i=0; i<n;

Exemplu – 8 regine (1) void dame(int k) {int i; if(k<n) { for(i=0; i<n; i++) { if(valid(k, i)) { tab[k]=i; dame(k+1); } } } else {print(); } }

Exemplu – 8 regine (2) int valid(int k, int i) { int j; for(j=0;

Exemplu – 8 regine (2) int valid(int k, int i) { int j; for(j=0; j<k; j++) { if(tab[j]==i){return 0; } if(abs(j-k)==abs(tab[j]-i)){return 0; } } return 1; }

Exemplu - săritura calului void cal(int x, int y, int pas) { if(!gata) {

Exemplu - săritura calului void cal(int x, int y, int pas) { if(!gata) { tab[x][y]=pas; if(pas==n*n) { print(); gata=1; return; } if((tab[x+1][y+2]==0)&&(x+1<=n)&&(y+2<=n))cal(x+1, y+2, pas+1); if((tab[x+2][y+1]==0)&&(x+2<=n)&&(y+1<=n))cal(x+2, y+1, pas+1); if((tab[x-1][y-2]==0)&&(x-1>=1)&&(y-2>=1))cal(x-1, y-2, pas+1); if((tab[x-2][y-1]==0)&&(x-2>=1)&&(y-1>=1))cal(x-2, y-1, pas+1); if((tab[x-1][y+2]==0)&&(x-1>=1)&&(y+2<=n))cal(x-1, y+2, pas+1); if((tab[x-2][y+1]==0)&&(x-2>=1)&&(y+1<=n))cal(x-2, y+1, pas+1); if((tab[x+1][y-2]==0)&&(x+1<=n)&&(y-2>=1))cal(x+1, y-2, pas+1); if((tab[x+2][y-1]==0)&&(x+2<=n)&&(y-1>=1))cal(x+2, y-1, pas+1); tab[x][y]=0; } }