Documente Academic
Documente Profesional
Documente Cultură
Raport
Disciplina Analiza și Proiectarea Algoritmilor
Tema: Metoda Divide et Impera
Chișinău-2019
Cuprins:
2. Descrierea algoritmilor………………………………….………………………..4
4. Concluzie…………………………………………………………………………7
Anexa A…………………………………………………………………………..8
Anexa B…………………………………………………………………………..14
1. Scopul și sarcina lucrării
1. Merge Sort:
şirul este împărţit până la jumătate în două subşiruri de lungimi egale (sau care diferă cu cel mult o unitate),
apoi prin recursivitate, cu subşirurile obţinute se procedează la fel, până ce subşirurile au lungime 1 sau cel
mult 2 elemente;
cele două subşiruri corespunzătoare ultimului apel recursiv sunt sortate;
subşirurile sortate se interclasează, prin revenirea din recursivitate reconstruindu-se treptat tot vectorul
iniţial sortat;
Dacă timpul de fuzionare de sortare pentru o listă cu lungimea n este T (n), atunci repetarea T (n) = 2T
(n / 2)+n.
Rezultă că în sortarea a n obiecte, Merge Sort are o performanță medie și cel mai rău caz de O (n log
n).
2. Quick Sort:
Pașii algoritmului:
1. Se alege un element al listei, denumit pivot
2. Se reordonează lista astfel încât toate elementele mai mici decât pivotul să fie plasate înaintea
pivotului şi toate elementele mai mari să fie după pivot. După această partiţionare, pivotul se află în
poziţia sa finală.
3. Se sortează recursiv sublista de elemente mai mici decât pivotul şi sublista de elemente mai mari
decât pivotul.
Algoritmii Merge Sort și Quick Sort au fost analizați la introducerea a 100, 1000, 10000 și 100000
numere. Au fost prelucrate 3 cazuri: cazul favorabil (când toate numerele sunt aranjate în ordine
crescătoare), mediu (când numerele sunt ordonate random) și defavorabil (când numerele sunt aranjate în
ordine descrescătoare). În calitate de criteriu de comparare a fost ales timpul de execuție al algoritmilor.
Timpul a fost măsurat în microsecunde.
Caz favorabil
60000000
50000000
40000000
30000000
20000000
10000000
0
100 1000 10000
50000000
40000000
30000000
20000000
10000000
0
100 1000 10000
Cazul defavorabil
60000000
50000000
40000000
30000000
20000000
10000000
0
100 1000 10000
#include <iostream>
#include <cmath>
#include <stdlib.h>
#include <time.h>
#include <chrono>
using namespace std::chrono;
using namespace std;
int itNr_m = 0;
int itNr_q = 0;
int v;
cout << "1. Caz favorabil" << endl;
cout << "2. Caz nefavorabil" << endl;
cout << "3. Random" << endl;
cin >> v;
if (v == 1) {
for (int i = 1; i <= nr; i++) {
a[i] = i;
}
}
else if (v == 2) {
nr = nr + 1;
for (int i = 1; i <= nr; i++) {
a[i] = nr - i;
}
}
else if (v == 3) {
for (int i = 1; i <= nr; i++) {
a[i] = rand() % nr + 1; ;
}
}
for (int i = 1; i <= nr; i++)
b[i] = a[i];
for (int i = 0; i <= nr; i++)
c[i] = a[i + 1];
}
}
else
{
a[k] = c[j];
j++;
}
k++;
}
}
}
if (l < r)
{
// Same as (l+r)/2, but avoids overflow for
// large l and h
int m = l+(r-l)/2;
itNr_m++;
// Sort first and second halves
mergeSort(a, l, m);
mergeSort(a, m+1, r);
merge(a, l, m, r);
}
}
itNr_q++;
swap(&a[i + 1], &a[high]);
return (i + 1);
}
}
}
/*meniu function*/
void meniuPr()
{
int f, k, nr;
//chrono::time_point<std::chrono::system_clock> start, end;
cout << endl << endl << " Meniu " << endl;
cout << " 1. MergeSort" << endl;
cout << " 2. QuickSort" << endl;
cout << " 0. Exit " << endl;
cin >> f;
if (f == 1)
{
system("cls");
itNr_m = 0;
cout << "Enter the number of values you want to sort: " << endl;
cout << "1. 100" << endl << "2. 1000" << endl << "3. 10000" << endl << "4. 100000" <<
endl;
cin >> k;
if (k == 1)
{nr = 100;}
else if ( k == 2 )
{nr = 1000;}
else if (k == 3)
{nr = 10000;}
else if (k == 4)
{nr = 100000;}
system("cls");
return;
}
if (f == 2)
{
system("cls");
itNr_q = 0;
cout << "Enter the number of values you want to sort: " << endl;
cout << "1. 100" << endl << "2. 1000" << endl << "3. 10000" << endl << "4. 100000" <<
endl;
cin >> k;
system("cls");
if (k == 1)
{nr = 100;}
else if ( k == 2 )
{nr = 1000;}
else if (k == 3)
{nr = 10000;}
else if (k == 4)
{nr = 100000;}
//int size = 0;
initData(nr);
cout << "Initial array: " << endl;
//printArray(a, nr);
cout << endl << endl << "Sorted array with QuickSort: " << endl;
auto start = high_resolution_clock::now();
quickSort(a, 0, nr - 1);
auto stop = high_resolution_clock::now();
printArray (a, nr);
auto duration = duration_cast<microseconds>(stop - start);
cout << endl << endl << "Nr of interations: " << itNr_q;
cout << endl << "Execution time: " << duration.count() << " milisec." << endl;
meniuPr();
return;
}
if (f == 0)
{
system("cls");
cout << "You exited the program.";
return;
}
else
{ system("cls");
cout << "No such option. Try another one.";
meniuPr();
}
int main()
{
meniuPr();
}
Anexa B
Concluzie
În cadrul lucrării de laborator nr. 2 au fost analizată tehnica de programare Divide et Impera pe exemplul
algoritmilor de sortare Merge Sort și Quick Sort.
Acești algoritmi au la bază tehnica Divide et Impera, adică ambii împart problema propusă în mai multe
subprobleme, le rezolvă și apoi le concatenează, astfel primind în rezultat problema inițial propusă
rezolvată. Pentru aceasta a fost creat un program care sortează șiruri de numere de diferite dimensiuni
(100, 1000, 10000, 100000) aranjate crescător, descrescător și random. În urma analei empirice a
algoritmilor, s-a determinat că mai efectiv în raport de timp este Merge Sort. Acesta sortează în
toate cazurile tablourile unidimensiionale de elemente într-un timp mai scurt decât Quick Sort.
Efectuînd lucrarea dată am implementat algoritmi de sortare, quicksort , mergesort si bubblesort, bazaţi
pe analizind timpul de executie al algoritmilor daţi.