Data Structures - Final Proyect 1
Data Structures - Final Proyect 1
Data Structures - Final Proyect 1
The QuickSort algorithm is based on the "divide and conquer" technique, so in each recursion, the problem is divided
into smaller subproblems, and they are solved separately (applying the same technique) to be joined again once solved.
This algorithm is also known as the "quick method" and "sort by partition".
In practice, it is the fastest known sort algorithm (as well as the most used in the world): its average execution time is O
(n log (n)), being in the worst case O (n2), highly unlikely event. The fact that it is faster than other sorting algorithms
with averaging time of O (n log (n)) (such as SmoothSort or HeapSort) is due to the fact that QuickSort performs fewer
operations since the method used is the partition method.
Pseudocode:
The efficiency of the algorithm depends on the position in which the chosen pivot ends. In the best case, the pivot ends
up in the center of the list, dividing it into two sub-lists of equal size. In this case, the order of complexity of the
algorithm is O (n * log n). In the worst case, the pivot ends up at one end of the list. The order of complexity of the
algorithm is then O (n²). The worst case will depend on the implementation of the algorithm, although it usually occurs
in lists that are ordered, or almost ordered. But mainly it depends on the pivot, if for example the implemented
algorithm always takes the first element of the array as a pivot, and the array that we pass to it is ordered, it will always
generate an empty array on its left, which is inefficient. In the average case, the order is O (n * log n). And it is not
surprising, then, that most of the optimizations that are applied to the algorithm focus on the choice of the pivot.
A good strategy to solve the widely used pivot selection is known as "three-way". In this strategy, what is sought is to
make an average with the values of three of the elements in the list. For example, if our list is [8, 4, 9, 3, 5, 7, 1, 6, 2] the
mean would be (8 + 2 + 5) / 3 = 5 which would give rise to the following partitions:
L1 = [8, 9, 7, 6]
L2 = [5]
L3 = [1, 2, 4, 3]
This strategy does not assure us that it will always give us the best selection of the pivot, but that statistically, the
selection of the pivot is good.
ALGORITHM IMPLEMENTATION (CODE):
i = first;
j = last;
do {
while (a[i] < pivot) i++;
while (a[j] > pivot) j--;
if (i <= j)
{
double tmp;
tmp = a[i];
a[i] = a[j];
a[j] = tmp; /* interchanges a[i] and a[j] */
i++;
j--;
}
}while (i <= j);
if (first < j)
quicksort(a, first, j); /* same process with the left sub-list */
if (i < last)
quicksort(a, i, last); /* same process with the right sub-list */
}
Complexity analisis:
In quick sort, all the actual work happens in the step of dividing the list into sub-lists; the step of combining the elements
has practically no effect on the algorithm's execution time.
Quick sort works in place and run time, worst case is just as bad as select sort and insert sort (Θ ^ 2). But the execution
time of your average case is only as good as that of the merge sort (Θ * n * log_2 (n)).
Code with which I tried to check the information found about the complexity of the "Quicksort" algorithm, since I have
not fully understood the procedure to manually calculate the complexity of a recursive algorithm:
#include <iostream>
#include <cstdlib>
#include <time.h>
#include <ctime>
i = first;
j = last;
do {
while (a[i] < pivot) i++;
while (a[j] > pivot) j--;
if (i <= j)
{
double tmp;
tmp = a[i];
a[i] = a[j];
a[j] = tmp; /* interchanges a[i] and a[j] */
i++;
j--;
}
}while (i <= j);
if (first < j)
quicksort(a, first, j); /* same process with the left sub-list */
if (i < last)
quicksort(a, i, last); /* same process with the right sub-list */
}
main()
{
srand(time(NULL));
clock_t tStart;
int cuantos=100;
for(int i=2; i<=cuantos; i+=2)
{
int DESDE=1;
int HASTA=9;
double *arreglo = new double[i];
for (int x = 1; x <= i; x++)
{
arreglo[x] = rand()%(HASTA-DESDE+1)+DESDE;
}
tStart = clock();
quicksort(arreglo, 0, i-1);
printf("%i: %.100fs\n", i, ((double)(clock() - tStart)/CLOCKS_PER_SEC));
}
}
Withthe previous algorithm I got some graphic results like this:
http://lwh.free.fr/pages/algo/tri/tri_rapide_es.html
http://cidecame.uaeh.edu.mx/lcc/mapa/PROYECTO/libro9/mtodo_quick_sort.html
https://www.genbeta.com/desarrollo/implementando-el-algoritmo-quicksort
https://sites.google.com/site/programacioniiuno/temario/unidad-6---anlisis-de-algoritmos/algoritmo-quicksort
https://www.mheducation.es/bcv/guide/capitulo/8448198441.pdf
https://es.khanacademy.org/computing/computer-science/algorithms/quick-sort/a/analysis-of-quicksort