160 likes | 433 Views
Algoritmi recursivi. Structuri de date şi algoritmi 1 - laborator - s.l . dr. ing. Ciprian-Bogdan Chiril ă Universitatea Politehnica Timi ş oara 2014. Cuprins. Ce este recursivitatea ? Verificarea şi simularea programelor recursive Tipuri de algoritmi recursivi
E N D
Algoritmi recursivi Structuri de date şi algoritmi 1 -laborator- s.l. dr. ing. Ciprian-BogdanChirilă UniversitateaPolitehnica Timişoara 2014
Cuprins • Ce este recursivitatea ? • Verificarea şi simularea programelor recursive • Tipuri de algoritmi recursivi • Algoritmi de traversare a unei structuri • Algoritmi care implementează definiţii recursive • factorial, Euclid, ridicarea la putere • Algoritmi de divizare • quicksort, căutarea binară • Algoritmi cu revenire (backtracking) • săritura calului, problema celor 8 regine • aranjamente (cu/fără repetiţie), combinări “de m luate câte n”
Ce este recursivitatea ? • 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 • 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 return 1; } else { // verificare pentru n>0 n!=n*(n-1)! return n*factorial(n-1); } }
Algoritmi care implementează definiţii recursiveExemplu – 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 element) /* apelul initialal procedurii se face cu primelemental structurii */ { prelucrare(element); if element != ultimul_din_structura traversare(element_urmator); }
Algoritmi de divizare void rezolva(problema x) { if /* x e divizibil in subprobleme */ { /* divide pe x in parti x1,...,xk */ rezolva(x1); /*…*/ rezolva(xk); /* combina solutiile partiale intr-o solutie pentru x */ } else /* rezolva pe x direct */ }
Algoritmi cu revenire (backtracking) • x=(x1,x2,...xn) € S=S1 x S2 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 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 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(); } int valid(int p) { if(p>0) { return tab[p]!=tab[p-1]; } return 1; }
Exemplu – combinări 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(); } int valid(int p) { if(p>0) { return tab[p]>tab[p-1]; } return 1; }
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;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) { 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; } }