16
Particiones de método de ordenamiento quicksort Oliver a. vilca huayta COLQUEHUANCA RODRIGO, Linio 091161

Tiempo de ejecucion de particiones (quicksort)

Embed Size (px)

Citation preview

Page 1: Tiempo de ejecucion de particiones (quicksort)

Particiones de método de

ordenamiento quicksort

Oliver a. vilca huayta

COLQUEHUANCA RODRIGO, Linio

091161

Page 2: Tiempo de ejecucion de particiones (quicksort)

2

PARTICIONES DE ORDENAMIENTO QUICKSORT

I. INTRODUCCION

Los computadores se emplean frecuentemente para almacenar y recuperar

grandes volúmenes de datos. Con su velocidad y facilidad de acceso, los

computadores aventajan a otros medios de almacenamiento como el papel

y las microfichas.

Es importante estudiar la forma en que los computadores pueden

almacenar los datos, de modo que su recuperación (búsqueda) sea rápida.

Para lograr esto, y puesto que usualmente los usuarios requieren que los

datos recuperados cuenten con algún orden particular, también es

importante estudiar algoritmos para ordenar los datos almacenados.

Para el caso del ordenamiento, el problema consiste en ordenar el vector

en forma ascendente (de menor a mayor). Si se quisiera trabajar con

ordenamiento descendente los cambios serían mínimos.

En este trabajo se verá el algoritmo de ordenamiento Quicksort

especialmente sus PARTICIONES que pueden ser implementadas de

diferentes formas que difieren entre sí en cuanto a su complejidad y

eficiencia.

Page 3: Tiempo de ejecucion de particiones (quicksort)

3

II. ORDENAMIENTO

Uno de los procedimientos más comunes y útiles en el procesamiento de

datos, es la clasificación u ordenación de los mismos. Se considera ordenar

al proceso de reorganizar un conjunto dado de objetos en una secuencia

determinada. Cuando se analiza un método de ordenación, hay que

determinar cuántas comparaciones e intercambios se realizan para el caso

más favorable, para el caso medio y para el caso más desfavorable.

La colocación en orden de una lista de valores se llama Ordenación. Por

ejemplo, se podría disponer una lista de valores numéricos en orden

ascendente o descendente, o bien una lista de nombres en orden

alfabético. La localización de un elemento de una lista se llama búsqueda.

Tal operación se puede hacer de manera más eficiente después de que la

lista ha sido ordenada.

Existen varios métodos para ordenamiento, clasificados en tres formas:

Intercambio

Selección

Inserción.

En cada familia se distinguen dos versiones: un método simple y directo,

fácil de comprender pero de escasa eficiencia respecto al tiempo de

ejecución, y un método rápido, más sofisticado en su ejecución por la

complejidad de las operaciones a realizar, pero mucho más eficiente en

cuanto a tiempo de ejecución. En general, para arreglos con pocos

elementos, los métodos directos son más eficientes (menor tiempo de

ejecución) mientras que para grandes cantidades de datos se deben

emplear los llamados métodos rápidos.

Page 4: Tiempo de ejecucion de particiones (quicksort)

4

III. QUICKSORT

El método Quicksort basa su estrategia en la idea intuitiva de que es más

fácil ordenar una gran estructura de datos subdividiéndolas en otras más

pequeñas introduciendo un orden relativo entre ellas. En otras palabras, si

dividimos el array a ordenar en dos subarrays de forma que los elementos

del subarray inferior sean más pequeños que los del subarray superior, y

aplicamos el método reiteradamente, al final tendremos el array inicial

totalmente ordenado. Existen además otros métodos conocidos, el de

ordenación por montículo y el de shell.

El algoritmo Quicksort fue desarrollado en 1962 por C.A.R. Hoare, antes de

que se implementaran los primeros lenguajes con capacidad para ejecutar

funciones recursivas.

3.1 Complejidad computacional del Quicksort:

En el mejor de los casos tiene un costo de O(n*log (n)). Que es cuando

el pibote siempre queda al medio del arreglo.

Quicksort Mejor caso

En el peor de los casos tiene un costo de O(n^2). Cuando el pibote

siempre se inclina hacia a un lado, es decir, genera una array de sólo 1

elemento y una segunda con el resto de elementos.

Quicksort peor caso

Page 5: Tiempo de ejecucion de particiones (quicksort)

5

En el caso promedio también tiene un costo de O(n*log (n)). Se

produce cuando el pibote se inclina más hacia un lado y los 2 subarrays

tienen distinto tamaño de elementos.

Quicksort caso promedio

Para calcular el tiempo de ejecución estoy usando la función clock() que

determina el tiempo usado por el procesador. En este caso defino 3

variables ini, final y total. 1ini=clock(); // Antes del quicksort:

2final = clock(); //Después que se ejecuta el quicksort

3total =((double)(final – ini)) /

4CLOCKS_PER_SEC; // El valor retornado por clock()

5debe ser dividido por el valor de la macro CLOCKS_PER_SEC

IV. Partición de método Cormen

Se tiene una array de n elementos, tomamos un valor del array como pivote

(usualmente el ultimo), separamos los elementos menor a este pivote a la

izquierda y los mayores a la derecha, es decir, dividimos el array en 2

subarrays.

Page 6: Tiempo de ejecucion de particiones (quicksort)

6

int PartitionCormen(double A[], int left,int right){

double pivote;

int i,j;

pivote = A[right];

i = left - 1;

for( j=left; j<=right-1; j++){

if(A[j]<pivote){

i++;

swap(A[i],A[j]);

}

}

swap(A[i+1],A[right]);

return i+1;

}

V. Partición de método Cormen modificado

Se tiene una array de n elementos, tomamos un valor del array como pivote

el primero, separamos los elementos menor a este pivote a la izquierda y

los mayores a la derecha, es decir, dividimos el array en 2 subarrays.

int PartitionCormenModificado(double A[], int left,int right){

double pivote;

int i,j;

pivote = A[left];

i = right + 1;

for( j=right; j>=left+1; j--){

if(A[j]<pivote){

i--;

swap(A[i],A[j]);

}

}

swap(A[i-1],A[left]);

return i-1;

}

De manera que el árbol recursivo de ordenación queda más o menos así:

Page 7: Tiempo de ejecucion de particiones (quicksort)

7

VI. Partición de método Brassard

Empezamos creando o generando un array de n elementos, por ejemplo yo

use la función rand() de c++ para generar aleatorios del 1 al 15:

a[] = {8, 1, 5, 14, 4, 15, 12, 6, 2, 11, 10, 7, 9};

izq der

0 1 2 3 4 5 6 7 8 9 10 11 12

8 1 5 14 4 15 12 6 2 11 10 7 9

Tomamos como pivote el 8 y usamos 2 índices que me indiquen la posición

del array: Uno que vaya de izquierda a derecha buscando los elementos

mayores al pivote. a[izq] Y un índice que busque de derecha a izquierda los

elementos menores al pivote. a[der] El índice izquierdo irá aumentando en

1 mientras el array en la posición izquierda sea menor o igual al pivote: 1while ((izq < der) && (array[izq] <= pibote)){

2 izq++;

3}

El índice derecho irá reduciéndose en 1 mientras el array en la posición

derecha sea mayor al pibote. 1while (array[der] > pibote){

2 der--;

3}

Si al final de estas 2 operaciones, el índice izquierdo es menor al derecho

se intercambian las posiciones a[izq] con a[der], usando una variable

temporal: En este caso, en la primer recorrido el índice izquierdo encuentra

al 14 (mayor al pivote) y el índice derecho al 7 (menor al pivote), y se

intercambian los índices:

8 1 5 14 4 15 12 6 2 11 10 7 9

8 1 5 7 4 15 12 6 2 11 10 14 9

Segundo recorrido: El índice izquierdo encuentra al 15 (mayor al pivote) y el

índice derecho al 2 (menor al pivote), se intercambian:

8 1 5 7 4 15 12 6 2 11 10 14 9

8 1 5 7 4 2 12 6 15 11 10 14 9

Tercer recorrido: El índice izquierdo encuentra al 12 (mayor al pivote) y el

índice derecho al 6 (menor al pivote), se intercambian:

8 1 5 7 4 2 12 6 15 11 10 14 9

8 1 5 7 4 2 6 12 15 11 10 14 9

Page 8: Tiempo de ejecucion de particiones (quicksort)

8

Cuando los índices se juntan o se cruzan ponemos el pivote en el lugar que

le corresponde en el array: 1temp = array[der];

2array[der] = array[inicio]; // el pibote está en el inicio del

array

3array[inicio] = temp;

Se intercambian el 8 con el 6 y el array quedaría así:

6 1 5 7 4 2 8 12 15 11 10 14 9

int ParticionBrassard(double A[], int left, int right){

int pivote = A[left];

int izq = left - 1;

int der = right + 1;

while (izq < der){

do{

izq++;

} while (A[izq] < pivote);

do {

der--;

} while (A[der] > pivote);

if (izq < der){

swap(A[izq],A[der]);

}

}

return(der);

}

VII. Partición 4

int Particion4(int *v, int b, int t){

int i;

int pivote, valor_pivote;

int temp;

pivote = b;

valor_pivote = v[pivote];

for (i=b+1; i<=t; i++){

if (v[i] < valor_pivote){

pivote++;

temp=v[i];

v[i]=v[pivote];

v[pivote]=temp;

}

}

temp=v[b];

v[b]=v[pivote];

v[pivote]=temp;

return pivote;

}

Page 9: Tiempo de ejecucion de particiones (quicksort)

9

VIII. Tiempo de ejecución de Particiones #include <stdio.h>

#include <stdlib.h>

#include <time.h>

#include <sys/times.h>

#include <sys/stat.h>

#include <math.h>

#include <string.h>

#include <unistd.h> // _SC_CLK_TCK The number of clock ticks per second;

#define Max_ind 32000

struct tms ti, tf, td;

double tsegundos,tsegundos2;

clock_t ta,tb,tc;

double Temp[Max_ind];

double tmp;

void IniT(){

ta=times(&ti);

printf("INI %f %f\n", (double)(ti.tms_utime),(double)ta );

}

void FinT(){

tb=times(&tf);

printf("FIN %f %f\n", (double)(tf.tms_utime),(double)tb );

td.tms_utime = tf.tms_utime-ti.tms_utime;

tc = tb - ta;

tsegundos =((double)(td.tms_utime))/sysconf(_SC_CLK_TCK);

tsegundos2 =((double)(tc))/sysconf(_SC_CLK_TCK);

printf("Pasaron = %lf %lf %lf \n",(double)tc, tsegundos, tsegundos2);

}

int PartitionCormen(double A[], int left,int right){

double pivote,temp;

int i,j;

pivote = A[right];

i = left - 1;

for( j=left; j<=right-1; j++){

if(A[j]<pivote){

i++;

temp=A[i];

A[i]=A[j];

A[j]=temp;

}

}

temp=A[i-1];

A[i+1]=A[right];

A[right]=temp;

return i+1;

}

int PartitionCormenMod(double A[], int left,int right){

double pivote,temp;

int i,j;

pivote = A[left];

i = right + 1;

for( j=right; j>=left+1; j--){

if(A[j]<pivote){

i--;

temp=A[i];

A[i]=A[j];

Page 10: Tiempo de ejecucion de particiones (quicksort)

10

A[j]=temp;

}

}

temp=A[i-1];

A[i-1]=A[left];

A[left]=temp;

return i-1;

}

int PartitionBrassard(double A[], int left, int right){

float temp;

int pivote = A[left];

int izq = left - 1;

int der = right + 1;

while (izq < der){

do{

izq++;

} while (A[izq] < pivote);

do {

der--;

} while (A[der] > pivote);

if (izq < der){

temp=A[izq];

A[der]=A[izq];

A[izq]=temp;

}

}

return(der);

}

int Partition4(int *v, int b, int t){

int i;

int pivote, valor_pivote;

int temp;

pivote = b;

valor_pivote = v[pivote];

for (i=b+1; i<=t; i++){

if (v[i] < valor_pivote){

pivote++;

temp=v[i];

v[i]=v[pivote];

v[pivote]=temp;

}

}

temp=v[b];

v[b]=v[pivote];

v[pivote]=temp;

return pivote;

}

main(int argc, char *argv[]){

int Nro_pruebas = 40;

int i,j,k,l;

double V1[Max_ind],V2[Max_ind],V3[Max_ind],V4[Max_ind],V5[Max_ind];

double V6[Max_ind],V7[Max_ind],V8[Max_ind],V9[Max_ind],V10[Max_ind];

double V11[Max_ind],V12[Max_ind],V13[Max_ind],V14[Max_ind],V15[Max_ind];

double V16[Max_ind],V17[Max_ind],V18[Max_ind],V19[Max_ind],V20[Max_ind];

double C1[Max_ind],C2[Max_ind],C3[Max_ind],C4[Max_ind],C5[Max_ind];

double C6[Max_ind],C7[Max_ind],C8[Max_ind],C9[Max_ind],C10[Max_ind];

Page 11: Tiempo de ejecucion de particiones (quicksort)

11

double C11[Max_ind],C12[Max_ind],C13[Max_ind],C14[Max_ind],C15[Max_ind];

double C16[Max_ind],C17[Max_ind],C18[Max_ind],C19[Max_ind],C20[Max_ind];

for(i=0;i<Max_ind;i++){

V1[i]=random();V2[i]=random();V3[i]=random();V4[i]=random();

V5[i]=random();V6[i]=random();V7[i]=random();V8[i]=random();

V9[i]=random();V10[i]=random();V11[i]=random();V12[i]=random();

V13[i]=random();V14[i]=random();V15[i]=random();V16[i]=random();

V17[i]=random();V18[i]=random();V19[i]=random();V20[i]=random();

}

for(j=0;j<Max_ind;j++){

C1[j]=V1[j];C2[j]=V2[j];C3[j]=V3[j];C4[j]=V4[j];

C5[j]=V5[j];C6[j]=V6[j];C7[j]=V7[j];C8[j]=V8[j];

C9[j]=V9[j];C10[j]=V10[j];C11[j]=V11[j];C12[j]=V12[j];

C13[j]=V13[j];C14[j]=V14[j];C15[j]=V15[j];C16[j]=V16[j];

C17[j]=V17[j];C18[j]=V18[j];C19[j]=V19[j];C20[j]=V20[j];

}

IniT();

for(i=0;i<Nro_pruebas;i++){

k=PartitionCormen(C1,0,Max_ind-1);k=PartitionCormen(C2,0,Max_ind-1);

k=PartitionCormen(C3,0,Max_ind-1);k=PartitionCormen(C4,0,Max_ind-1);

k=PartitionCormen(C5,0,Max_ind-1);k=PartitionCormen(C6,0,Max_ind-1);

k=PartitionCormen(C7,0,Max_ind-1);k=PartitionCormen(C8,0,Max_ind-1);

k=PartitionCormen(C9,0,Max_ind-1);k=PartitionCormen(C10,0,Max_ind-

1);

k=PartitionCormen(C11,0,Max_ind-1);k=PartitionCormen(C12,0,Max_ind-

1);

k=PartitionCormen(C13,0,Max_ind-1);k=PartitionCormen(C14,0,Max_ind-

1);

k=PartitionCormen(C15,0,Max_ind-1);k=PartitionCormen(C16,0,Max_ind-

1);

k=PartitionCormen(C17,0,Max_ind-1);k=PartitionCormen(C18,0,Max_ind-

1);

k=PartitionCormen(C19,0,Max_ind-1);k=PartitionCormen(C20,0,Max_ind-

1);

}

FinT();

printf("\n");

for(j=0;j<Max_ind;j++){

V1[j]=C1[j];V2[j]=C2[j];V3[j]=C3[j];V4[j]=C4[j];

V5[j]=C5[j];V6[j]=C6[j];V7[j]=C7[j];V8[j]=C8[j];

V9[j]=C9[j];V10[j]=C10[j];V11[j]=C11[j];V12[j]=C12[j];

V13[j]=C13[j];V14[j]=C14[j];V15[j]=C15[j];V16[j]=C16[j];

V17[j]=C17[j];V18[j]=C18[j];V19[j]=C19[j];V20[j]=C20[j];

}

IniT();

for(i=0;i<Nro_pruebas;i++){

k=PartitionCormenMod(C1,0,Max_ind-

1);k=PartitionCormenMod(C2,0,Max_ind-1);

k=PartitionCormenMod(C3,0,Max_ind-

1);k=PartitionCormenMod(C4,0,Max_ind-1);

k=PartitionCormenMod(C5,0,Max_ind-

1);k=PartitionCormenMod(C6,0,Max_ind-1);

Page 12: Tiempo de ejecucion de particiones (quicksort)

12

k=PartitionCormenMod(C7,0,Max_ind-

1);k=PartitionCormenMod(C8,0,Max_ind-1);

k=PartitionCormenMod(C9,0,Max_ind-

1);k=PartitionCormenMod(C10,0,Max_ind-1);

k=PartitionCormenMod(C11,0,Max_ind-

1);k=PartitionCormenMod(C12,0,Max_ind-1);

k=PartitionCormenMod(C13,0,Max_ind-

1);k=PartitionCormenMod(C14,0,Max_ind-1);

k=PartitionCormenMod(C15,0,Max_ind-

1);k=PartitionCormenMod(C16,0,Max_ind-1);

k=PartitionCormenMod(C17,0,Max_ind-

1);k=PartitionCormenMod(C18,0,Max_ind-1);

k=PartitionCormenMod(C19,0,Max_ind-

1);k=PartitionCormenMod(C20,0,Max_ind-1);

}

FinT();

printf("\n");

for(j=0;j<Max_ind;j++){

V1[j]=C1[j];V2[j]=C2[j];V3[j]=C3[j];V4[j]=C4[j];

V5[j]=C5[j];V6[j]=C6[j];V7[j]=C7[j];V8[j]=C8[j];

V9[j]=C9[j];V10[j]=C10[j];V11[j]=C11[j];V12[j]=C12[j];

V13[j]=C13[j];V14[j]=C14[j];V15[j]=C15[j];V16[j]=C16[j];

V17[j]=C17[j];V18[j]=C18[j];V19[j]=C19[j];V20[j]=C20[j];

}

IniT();

for(i=0;i<Nro_pruebas;i++){

k=PartitionBrassard(C1,0,Max_ind-

1);k=PartitionBrassard(C2,0,Max_ind-1);

k=PartitionBrassard(C3,0,Max_ind-

1);k=PartitionBrassard(C4,0,Max_ind-1);

k=PartitionBrassard(C5,0,Max_ind-

1);k=PartitionBrassard(C6,0,Max_ind-1);

k=PartitionBrassard(C7,0,Max_ind-

1);k=PartitionBrassard(C8,0,Max_ind-1);

k=PartitionBrassard(C9,0,Max_ind-

1);k=PartitionBrassard(C10,0,Max_ind-1);

k=PartitionBrassard(C11,0,Max_ind-

1);k=PartitionBrassard(C12,0,Max_ind-1);

k=PartitionBrassard(C13,0,Max_ind-

1);k=PartitionBrassard(C14,0,Max_ind-1);

k=PartitionBrassard(C15,0,Max_ind-

1);k=PartitionBrassard(C16,0,Max_ind-1);

k=PartitionBrassard(C17,0,Max_ind-

1);k=PartitionBrassard(C18,0,Max_ind-1);

k=PartitionBrassard(C19,0,Max_ind-

1);k=PartitionBrassard(C20,0,Max_ind-1);

}

FinT();

printf("\n");

for(j=0;j<Max_ind;j++){

V1[j]=C1[j];V2[j]=C2[j];V3[j]=C3[j];V4[j]=C4[j];

V5[j]=C5[j];V6[j]=C6[j];V7[j]=C7[j];V8[j]=C8[j];

V9[j]=C9[j];V10[j]=C10[j];V11[j]=C11[j];V12[j]=C12[j];

Page 13: Tiempo de ejecucion de particiones (quicksort)

13

V13[j]=C13[j];V14[j]=C14[j];V15[j]=C15[j];V16[j]=C16[j];

V17[j]=C17[j];V18[j]=C18[j];V19[j]=C19[j];V20[j]=C20[j];

}

IniT();

for(i=0;i<Nro_pruebas;i++){

k=Partition4(C1,0,Max_ind-1);k=Partition4(C2,0,Max_ind-1);

k=Partition4(C3,0,Max_ind-1);k=Partition4(C4,0,Max_ind-1);

k=Partition4(C5,0,Max_ind-1);k=Partition4(C6,0,Max_ind-1);

k=Partition4(C7,0,Max_ind-1);k=Partition4(C8,0,Max_ind-1);

k=Partition4(C9,0,Max_ind-1);k=Partition4(C10,0,Max_ind-1);

k=Partition4(C11,0,Max_ind-1);k=Partition4(C12,0,Max_ind-1);

k=Partition4(C13,0,Max_ind-1);k=Partition4(C14,0,Max_ind-1);

k=Partition4(C15,0,Max_ind-1);k=Partition4(C16,0,Max_ind-1);

k=Partition4(C17,0,Max_ind-1);k=Partition4(C18,0,Max_ind-1);

k=Partition4(C19,0,Max_ind-1);k=Partition4(C20,0,Max_ind-1);

}

FinT();

}

Prueba1

Prueba2

Page 14: Tiempo de ejecucion de particiones (quicksort)

14

Prueba3

Page 15: Tiempo de ejecucion de particiones (quicksort)

15

IX. Conclusión

X. BIBLIOGRAFIA Fundamentos de Algoritmia-Brassard

McGraw.Hill.Introduction.To.Algorithms.segunda.Edicion

http://es.wikipedia.org/wiki/Quicksort

http://c.conclase.net/

0

5

10

15

20

25

30

35

Cormen CormenMod Brassard Particion4

Prueba 1

Prueba 2

Prueba 3

Page 16: Tiempo de ejecucion de particiones (quicksort)

16

PARTICIONES DE ORDENAMIENTO QUICKSORT ........................................................... 2

I. INTRODUCCION ......................................................................................................... 2

II. ORDENAMIENTO ....................................................................................................... 3

III. QUICKSORT ........................................................................................................... 4

3.1 Complejidad computacional del Quicksort: ........................................................ 4

IV. Partición de método Cormen ............................................................................... 5

V. Partición de método Cormen modificado .............................................................. 6

VI. Partición de método Brassard ............................................................................. 7

VII. Partición 4 ............................................................................................................... 8

VIII. Tiempo de ejecución de Particiones ................................................................... 9

IX. Conclusión............................................................................................................ 15

X. BIBLIOGRAFIA ......................................................................................................... 15