Sunteți pe pagina 1din 9

Ministerul Educaiei si tiinei al Republicii Moldova

Universitatea Tehnica a Moldovei

Facultatea Calculatoare , Informatica si Microelectronica

Catedra Calculatoare

Lucrare de laborator nr.2


Analiza si Proiectarea Algoritmilor Tema: Metoda divide et impera.

A executat studentul gr FI-101 :

Chihai Alexandru

A verificat :

Catruc Mariana

Chiinu 2011

Scopul lucrarii :
1. Studierea metodei divide si impera. 2. Analiza si implementarea algoritmilor bazati pe metoda ,,divide si impera Algoritmii Divide si Impera sunt : 1.1. 1.2. Mergesort Quicksort

1. Mergesort (sortarea prin interclasare)


MERGE- SORT (A, p, r) 1. if p< r 2. then q [(p + r)/2] 3. MERGE-SORT (A, p, q) 4. MERGE-SORT (A, q+1, r) 5. MERGE (A, p, q, r) Acum putem utiliza procedura MERGE ca subrutin pentru algoritmul de sortare prin interclasare.
Procedura MERGE- SORT (A, p, r) sorteaz elementele din subvectorul A[p,..r]. Dac p r, subvectorul are cel mult un element i este, prin urmare, deja sortat. Astfel pasul de divizare este prezent aici prin simplul calcul al unui indice q care mparte A[p..r] n doi subvectori A[p..q], coninnd [n/2] elemente i A[q+1..r] coninnd [n/2] elemente.

Pentru a determina recurena pentru T(n), timpul de execuie al sortrii prin interclasare a n numere, n cazul cel mai defavorabil, vom raiona n felul urmtor. Sortarea prin interclasare a unui singur element are nevoie de un timp constant. Cnd avem n>1 elemente, vom descompune timpul de execuie dup cum urmeaz:

Divide: La acest pas, se calculeaz doar mijlocul subvectorului, calcul care are nevoie de un timp constant de execuie. Astfel, D(n) = (1). Stpnete: Rezolvm recursiv dou probleme fiecare de dimensiune n/2,care contribuie cu 2T(n/2) la timpul de execuie. Combin: Am observat, deja c procedura MERGE pentru un subvector cu n elemente consum (n) timp de execuie, deci C(n)= (n).

Cnd adunm funciile D(n) i C(n) pentru analiza sortrii prin interclasare, adunm o funcie cu timpul de execuie (1). Aceast sum este o funcie linear n raport cu n, adic are timpul de execuie (n). Adugnd aceasta la termenul 2T(n/2) de la pasul stpnete, obinem timpul de execuie T(n) in cazul cel mai defavorabil pentru sortarea prin interclasare:
n =1 (1), T ( n) = 2T (n / 2) + ( n), n > 1

Se poate arta c T(n) este (nlgn) unde lgn reprezint log2n. Pentru numere suficient de mari, sortarea prin interclasare, are timpul de execuie (nlgn).

Listingul programului:
//Mergesort #include<stdio.h> #include<conio.h> #include<stdlib.h> #include<dos.h> int tab[2000],tab1[2000],n,ctr=0; int timerc(int s,int s1, int hr, int hr1) { int y,y1,y2,y3,y4; y=s*100+s1; y1=hr*100+hr1; y2=y1-y; y3=y2/100; y4=y2%100; printf("\nLe temp d'execution: %d:%d",y3,y4); return 1; } void insert(int a,int b) { int aux,i,k; for(i=a;i<b;i++) for(k=1;k<b+1-i;k++) if (tab[i+k]<tab[i]) { ctr=ctr+1; aux=tab[i]; tab[i]=tab[i+k]; tab[i+k]=aux; } } void merge (int a,int b,int f) { int c[2000],i,j,k; i=a; j=f+1; k=0; for(k=0;k<=b-a;k++) if(i<=f && j<=b) if(tab[i]<=tab[j]) { c[k]=tab[i]; i++; } else { c[k]=tab[j]; j++; } else if(i>f) { c[k]=tab[j]; j++; } else { c[k]=tab[i]; i++; }

k=0; for (i=a;i<=b;i++) { tab[i]=c[k]; k=k+1; } } void mergesort (int a,int b) { int f; if ((b-a)<=50) insert(a,b); else { f=(a+b)/2; mergesort(a,f); mergesort(f+1,b); merge(a,b,f); } } void quicksort(int tab[],int st,int dr) { int i,j; int v,t; if(dr>st) { v=tab[dr];i=st-1;j=dr; for(;;) {while(tab[++i]<v); while(tab[--j]>v); if(i>=j)break; t=tab[i];tab[i]=tab[j];tab[j]=t;ctr=ctr+1; } ctr=ctr+1; t=tab[i];tab[i]=tab[dr];tab[dr]=t; quicksort(tab,st,i-1); quicksort(tab,i+1,dr); } } void main() { int i; struct time t; int s,s1,hr,hr1; clrscr(); printf("Dati dimensiunea tabelului:\n"); printf("n="); scanf("%d",&n); // randomize(); for(i=0;i<n;i++) tab[i]=random(100); printf("\n"); printf("Tabelul initial:\n"); for(i=0;i<n;i++) { printf("%d ",tab[i]); } gettime(&t);

s=t.ti_sec; s1=t.ti_hund; mergesort(0,n-1); gettime(&t); hr=t.ti_sec; hr1=t.ti_hund; printf("\nTabelul ce reiese din met. Merge_Sort:\n"); for (i=0;i<n;i++) printf("%d ",tab[i]); printf("\nNumarul de iteratii este: %d",ctr); ctr=0; quicksort(tab,0,n-1); gettime(&t); hr=t.ti_sec; hr1=t.ti_hund; printf("\n\n"); printf("La tableau sorte par Quick_Sort:\n"); for(i=0;i<n;i++) printf("%d ",tab[i]); printf("\nLe nombre d'iterations: %d", ctr); getch(); }

Rezultatul

#include<stdio.h> #include<conio.h> #include<dos.h> #include<stdlib.h> long n; int *tab,*c; int ctr; void insert(int a,int b) { int aux,i,k; for(i=a;i<b;i++) for(k=1;k<b+1-i;k++) if (tab[i+k]<tab[i]) { ctr=ctr+1;

aux=tab[i]; tab[i]=tab[i+k]; tab[i+k]=aux; } } void merge (long a,long b,long f) { //printf(" 1 "); long i,j,k; i=a; j=f+1; k=0; for(k=0;k<=b-a;k++) if(i<=f && j<=b) if(tab[i]<=tab[j]) { c[k]=tab[i]; i++; } else { c[k]=tab[j]; j++; } else if(i>f) { c[k]=tab[j]; j++; } else { c[k]=tab[i]; i++; } k=0; for (i=a;i<=b;i++) { tab[i]=c[k]; k=k+1; } } void mergesort (long a,long b) { long f; if ((b-a)<=50) insert(a,b); else { f=(a+b)/2; mergesort(a,f); mergesort(f+1,b); merge(a,b,f); } } void main() { struct time t; int s,s1,hr,hr1; long i; clrscr(); printf("Dati dimensiunea tabelului:\n"); printf("n="); scanf("%d",&n); tab=new int (n);

c=new int (n); for(i=0;i<n;i++) tab[i]=random(500); gettime(&t); printf("Timpul curent este: %2d:%02d:%02d.%02d\n", t.ti_hour, t.ti_min, t.ti_sec, t.ti_hund); delay(80); // mergesort(0,n-1); gettime(&t); printf("Timpul curent este: %2d:%02d:%02d.%02d\n", t.ti_hour, t.ti_min, t.ti_sec, t.ti_hund); getch();}

REZULTATUL

2. Quicksort (sortarea rapida)


Pseudocodul pentru quicksort:
procedure quicksort(T[i .. j]) {sorteaz n ordine cresctoare tabloul T[i .. j]} if j este mic i then insert(T[i .. j]) else pivot(T[i .. j], l) {dup pivotare, avem: i k < l T[k] T[l] l < k j T[k] > T[l]} quicksort(T[i .. l 1]) quicksort(T[l+1 .. j]) procedure pivot(T[i .. j], l) {permut elementele din T[i .. j] astfel nct, n final, elementele lui T[i .. l sunt p, 1] T[l] = p, iar elementele lui T[l+1 .. j] sunt > p} p T[i]

k i; l j+1 repeat k k+1 until T[k] > p or k j repeat l l until T[l] p 1 while k < l do interschimb T[k] i T[l] repeat k k+1 until T[k] > p repeat l l until T[l] p 1 {pivotul este mutat n poziia lui final} interschimb T[i] i T[l] Operaia de pivotare necesit un timp n (n). Fie constanta n0, astfel nct, n cazul cel mai nefavorabil, timpul pentru a sorta n > n0 elemente prin quicksort s fie t(n) (n) + max{t(i)+t(n 1) | 0 i n i 1} Folosim metoda induciei constructive pentru a demonstra independent c t O(n2) i t (n2). Putem considera c exist o constant real pozitiv c, astfel nct t(i) ci2+c/2 pentru 0 i n0. Prin ipoteza induciei specificate parial, presupunem c t(i) ci2+c/2 pentru orice 0 i < n. Demonstrm c proprietatea este adevrata i pentru n. Avem t(n) dn + c + c max{i2+(n 1)2 | 0 i n i 1} d fiind o alt constant. Expresia i2+(n 1)2 i atinge maximul atunci cnd i este 0 sau n Deci: i 1. 2 2 t(n) dn + c + c(n = cn + c/2 + n(d + 3c/2 1) 2c) Dac lum c 2d, obinem t(n) cn2+c/2. Am artat c, dac c este suficient de mare, atunci t(n) cn2+c/2 pentru orice n 0, adic, t O(n2). Analog se arat c t (n2). Am artat, totodat, care este cel mai nefavorabil caz: atunci cnd, la fiecare nivel de recursivitate, procedura pivot este apelata o singur dat. Dac elementele lui T sunt distincte, cazul cel mai nefavorabil este atunci cnd iniial tabloul este ordonat cresctor sau descresctor, fiecare partiionare fiind total neechilibrat. Pentru acest cel mai nefavorabil caz, am artat c algoritmul quicksort necesit un timp n n2). Pentru caz favorabil avem O(n*log(n)). (

Analiza empirica Mergesort:


Num. de date Num. de iteratii obtinute de program Caz favorabil 100 200 300 500 700 900 1000 0 0 0 0 0 0 0 Caz nefavorabil 95 220 368 911 1320 1344 1428 Mediu 1014 2208 2733 4021 8922 8160 8461

Analiza empirica Quicksort:


Num. de date Num. de iteraii obinute de program Caz favorabil 100 200 300 500 700 900 1000 99 199 299 499 699 899 999 Caz nefavorabil 1642 2078 1783 1781 2386 1554 1784 Mediu 169 399 647 1216 1830 2479 2749

Concluzie: Algoritmul de sortare Mergesort (de cele mai multe ori) este putin mai lent decit Quicksort insa el are un timp stabil de executie, Quicksort- timpul lui de executie depinde de alegerea pivotului, daca valoarea acestuia se afla aproximativ in mijlocul tabloului sortat timpul de executie scade (devine mai rapiddecit mergesort) , insa daca de fiecare data valoarea pivotului se afla la extreme timpul poate creste pina n*n. Aceste considerente trebue de luat in seama la alegerea metodei de sortare.