Documente Academic
Documente Profesional
Documente Cultură
RAPORT
Disciplina: Analiza i proiectarea algoritmilor
Lucrare de laborator Nr.2
Tema: Metoda divide et impera
A efectuat :
A verificat:
Bagrin Veronica
Chisinau 2012
Scopul lucrrii:
1
17
17
16
16
8
Rezulta:
Rezulta:
3
Ceea ce inseamna ca cele doua secvente determina obtinerea urmatorului subsir din vector:
7
17
16
Se obtine:
6
4
Care se interclaseaza si se obtine:
4
La fel pentru:
17
16
Se obtine:
16
17
Se obtine o noua secventa:
4
16
17
16
17
16
17
Arborele de recursivitate pentru Quicksort cnd procedura Partiie pune ntotdeauna ntr-o parte a vectorului numai un
singur element (cazul cel mai defavorabil). Timpul de execuie n acest caz este O(n^2).
Partitionarea in cazul cel mai favorabil.
Daca algoritmul de partiionare produce doi vectori de n/2 elemente, algoritmul de sortare rapid lucreaz mult mai
repede.
Arborele de recuren pentru Quicksort cnd procedura Partiie produce ntotdeauna pari egale (cazul cel mai
favorabil). Timpul de execuie rezultat este O(n log2 n).
Costul total al algoritmului de sortare rapid este deci O(n log2 n). Ca urmare, cu o partiionare n proporie de 9 la 1
la fiecare nivel al partiionrii (care intuitiv pare a fi total dezechilibrata), algoritmul de sortare rapid are un timp de
execuie de O(n log2 n) asimptotic acelai ca n cazul partiionrii n dou pari egale. De fapt, timpul de execuie va
fi O(n log2 n) i n cazul partiionrii ntr-o proporie de 99 la 1. La orice partiionare ntr-o proporie constanta,
adncimea arborelui de recursivitate este O(log2 n) i costul, la fiecare nivel, este O(n). Deci timpul de execuie este
O(n log2 n) la orice partiionare ntr-o proporie constant.
Bubble-Sort
Considerm tabloul A cu 5 elemente numere reale: 0.0, 1.1, 1.0, 1.2 i 0.08. Prima parcurgere a tabloului (ok este
iniializat cu adevrat):
a1 = 0.0
a2 = 1.1
0.0
0.0
1.0
1.0
a3 = 1.0
a4 = 1.2
a5 = 0.08
ok
1.1
1.2
0.08
fals
1.2
fals
1.1
0.08
Valorile 0.0 < 1.1, rmn neschimbate, 1.1 > 1.0, le interschimbm. Deoarece 1.1 < 1.2, avansm i constatm
c 1.2 > 0.0.8, deci din nou avem interschimbare. n consecin, la ieire din structura
pentru ok este fals. Observm c 1.2 a ajuns pe locul lui definitiv. Urmeaz a doua parcurgere a tabloului
(ok primete din nou valoarea adevrat).
a1 = 0.0
a2 = 1.0
0.0
1.0
a3 = 1.1
0.08
a4 = 0.08
a5 = 1.2
ok
1.1
1.2
fals
Am avut interschimbare i de data aceasta, deci ieim cu ok = fals. La acest pas 1.1 a ajuns pe locul su definitiv.
A treia parcurgere a tabloului ncepe cu reiniializarea lui ok cu valoarea adevrat.
a1 = 0.0
a2 = 1.0
0.0
a3 = 0.08
a4 = 1.1
a5 = 1.2
ok
1.0
1.1
1.2
fals
0.08
Am interschimbat 0.08 cu 1.0, cel din urm astfel a ajuns pe locul su n irul ordonat. A patra parcurgere a
tabloului se finalizeaz cu valoarea ok = adevrat, deoarece nu am efectuat nici o interschimbare, ceea ce
nseamn c procesul de ordonare s-a ncheiat.
a1 = 0.0
a2 = 0.08
a3 = 1.0
a4 = 1.1
a5 = 1.2
ok
0.08
1.0
1.1
1.2
adevrat
0.0
Mergesort:
Listingul programului
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
int * sort(int stinga[], int dreapta[], int lS, int lD);
int * Imparte(int a[], int lungime);
void MergeSort(int * a, int nrElemente);
int contor = 0;
int main()
{
srand(time(0));
int * a, nrE;
clock_t start, sfirsit;
cout << "Introduceti nr de elemente: ";
cin >> nrE;
a = new int[nrE];
for (int i = 0; i < nrE; i++)
{
a[i] = 0 + rand() % ((15000 + 1) - 0);
}
cout<<endl<<"Marimea tabelului este:"<<endl;
for (int i=0;i<nrE;i++)
{
cout<<a[i]<<" ";
}
start = clock();
MergeSort(a, nrE);
sfirsit = clock();
cout<<endl<<"Tabelul sortat este: \n"<<endl;
for (int i=0;i<nrE;i++)
{
cout << a[i]<<" ";
7
}
cout << "\nTimpul de executie: " << (sfirsit - start) / CLOCKS_PER_SEC << " sec." << endl;
cout << "Nr de iteratii: " << contor << endl;
delete [] a;
cin.get();
cin.get();
return 0;
}
void MergeSort(int * a, int nrElemente)
{
int * x = Imparte(a, nrElemente);
for (int i = 0; i < nrElemente; i++)
{
a[i] = x[i];
}
delete [] x;
}
int * Imparte(int a[], int lungime)
{
if (lungime <= 1)
{
return a;
}
int * stinga, * dreapta;
int jumatate = lungime / 2;
stinga = new int[jumatate];
dreapta = new int[lungime - jumatate];
for (int i = 0; i < jumatate; i++)
{
stinga[i] = a[i];
}
for (int i = jumatate; i < lungime; i++)
{
dreapta[i - jumatate] = a[i];
}
stinga = Imparte(stinga, jumatate);
dreapta = Imparte(dreapta, lungime - jumatate);
int * x = sort(stinga, dreapta, jumatate, lungime - jumatate);
delete [] stinga;
delete [] dreapta;
return x;
}
int * sort(int stinga[], int dreapta[], int lS, int lD)
{
int * rezultat = new int[lS + lD];
int indS = 0, indD = 0, indR = 0;
while(lS > 0 || lD > 0)
{
if (lS > 0 && lD > 0)
{
if (stinga[indS] <= dreapta[indD])
{
contor++;
rezultat[indR++] = stinga[indS++];
lS--;
8
}
else
{
rezultat[indR++] = dreapta[indD++];
lD--;
}
}
else if (lS > 0)
{
contor++;
rezultat[indR++] = stinga[indS++];
lS--;
}
else if (lD > 0)
{
contor++;
rezultat[indR++] = dreapta[indD++];
lD--;
}
}
return rezultat;
}
Rezultatul executiei:
QUICKSORT:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include<time.h>
using namespace std;
int contor=0;
void sort_rapida(int tablou[], int prim, int ultim)
{
int temp, min, max, separator_lista;
min=prim;
max=ultim;
separator_lista=tablou[(prim+ultim)/2];
do
{
while(tablou[min] < separator_lista)
{
min++;
}
while(tablou[max] > separator_lista)
{
contor++;
max--;
}
if(min<=max)
{
10
contor++;
temp=tablou[min];
tablou[min++]=tablou[max];
tablou[max--]=temp;
}
}while(min<=max);
if(prim<max)
{
contor++;
sort_rapida(tablou, prim, max);
}
if(min<ultim)
{
contor++;
sort_rapida(tablou, min, ultim);
}
}
int main()
{
time_t start,end;
double dif;
int val[19000], i=0, n=0;
cout<<"Introduceti numarul de elemente: ";
cin>>n;
cout<<endl<<"Marimea tabloului este: "<<endl;
for(i=0; i<n; i++)
{
val[i]=rand()%100;
cout<<val[i]<<' ';
}
time (&start);
cout<<endl;
sort_rapida(val, 0, n);
time (&end);
dif = difftime (end,start);
cout<<endl<<"Tabloul sortat: "<<endl;
for(i=1; i<=n; i++)
{
cout<<val[i]<<' ';
}
cout<<endl;
printf("timp de executie: %.2lf secunde\n\n",dif);
cout<<endl<<"Numarul de iteratii este: "<<contor<<endl;
getch();
return 0;
}
11
Rezultatul executiei:
12
Bubble-Sort:
#include <iostream>
#include<stdlib.h>
#include<time.h>
using namespace std;
int contor=0;
int main()
{
time_t start,end;
double dif;
int v[100000],i,n,gasit,aux;
cout<<"Introduceti numarul n= ";cin>>n;
for(i=1;i<=n;i++)
{
v[i]=rand()%100;
cout<<v[i]<<" ";
}
time (&start);
do
{
gasit=0;
for(i=1;i<=n;i++)
if(v[i]>v[i+1])
{
contor++;
aux=v[i];
v[i]=v[i+1];
v[i+1]=aux;
gasit=1;
}
time (&end);
dif = difftime (end,start);
}
while(gasit==1);
cout<<"\nVectorul sortat este: \n";
for(i=1;i<=n;i++)
cout<<v[i]<<" ";
cout<<endl;
printf("timp de executie: %.2lf secunde\n\n",dif);
cout<<endl<<"Numarul de iteratii este:"<<contor<<endl;
return 0;}
13
14
Mergesort
10
QuickSort
22
Bubble-Sort
36
27
100
394
493
2708
1000
5656
7443
249579
100000
72322
80283
24945162
Mergesort
80000
72322
70000
60000
50000
40000
30000
20000
10000
22
394
0
10
100
5656
1000
Column1
15
10000
QuickSort
90000
80283
80000
70000
60000
50000
40000
30000
20000
7443
10000
36
493
01
10
2
100
3
1000
4
10000
Column1
Bubble-Sort
30000000
24945162
25000000
20000000
15000000
10000000
5000000
27
2708
249579
01
10
2
100
3
1000
4
10000
Iteratii
Concluzie
In urma analizei algoritmelor propuse se poate de spus ca algoritmul Mergesort este mai universal ,
avnd rezultate mai performante n mai multe cazuri ncercate fapt care rezulta din datele care li-am introdus
observind ca la numerge mici numarul de iterati nu variaza pe intervale foarte mari din cauza ca este simplu
de facut injumatatirea si la Mergesort timpul execuiei fiind mult mai mic dect la Quicksort . dar n schimb
Quicksort se comporta mai performant n cazuri generale , pentru numrul de valori mari date aleatoriu .La
fel si algoritumul Bubble-Sort observ ca pentru numerele mici care i le dau obtin un numar mic de
iteratii,obtinind chiar cel mai bun rezultat cind ii dau valoarea 5 dar algoritmul se incepe a schimba odata ce
incepe a creste valoarea numerica incepe a creste brusc si numarul de iteratii.Deci algoritmul mergesort este
mai static din punct de vedere a diferitor variante ,metoda lui fiind simpl njumtire , pe cind quicksort
16
este mai variabil pentru cazuri diferite , avind o metoda dependenta de aranjarea iniiala a
variabilelor.Bubble-Sort se comporta si el aproximatic ca Quicksort in dependenta de cum sunt aranjate
initial variabilele de asta depinde si inteschimbare dintre numere .
In general cea mi eficienta metoda este Mergesort prin care simpla injumatatire ne faciliteaza
sortarea.Aceasta metoda nu este dependenta de aranjarea initiala a variabilelor fapt care o face sa domine
metoda Quicksort si Bubble-Sort pentru ca la inregistrarea unor numere random nu se stie ce pozitie vor lua
numerele.
17