modulo 13

Anuncio
MODULO 13
OBJETIVOS
Por medio de este módulo se pretende:
-
Presentar los métodos básicos de ordenamiento de datos
-
Comparar estos métodos entre si y determinar su eficiencia
CONTENIDO
1. Algoritmos de Ordenamiento
1.1 Burbuja
1.2 Burbuja Mejorado
1.3 Selección
1.4 Inserción
A Referencias
1. ALGORITMOS DE ORDENAMIENTO
1.1 MÉTODO DE LA BURBUJA
Este método es muy sencillo de programar pero es bastante ineficiente. Consiste en comparar
los elementos adyacentes a ordenar e intercambiar sus valores si están desordenados
void burbuja(int *arreglo, int n)
{
int aux,i,j;
1
for(i=0;i<n-1;i++){
(n-1)+1
for(j=0;j<n-i-1;j++){
(n2-n)/2 + (n-1)
if(arreglo[j] > arreglo[j+1]){
(n2-n)/2
aux=arreglo[j];
(n2-n)/2
arreglo[j]=arreglo[j+1];
(n2-n)/2
arreglo[j+1]=aux;
(n2-n)/2
}
(n2-n)/2
}
(n2-n)/2
}
(n-1)
}
-------------2 + 3(n-1) + 7((n2-n)/2)
2
Orden: O(n )
1.2 MÉTODO DE LA BURBUJA MEJORADO
Constituye una mejora ya que el algoritmo termina inmediatamente cuando los datos ya están
ordenados
Detecta que los datos ya están ordenados porque no se producen intercambios (bandera es
igual a 0 al terminar el ciclo interno)
El algoritmo sigue siendo O(n2) para el peor caso (se comporta prácticamente igual que el
anterior), aunque si la lista de datos a ordenar ya viene ordenada (mejor caso) el algoritmo es
O(n) a diferencia de la versión anterior que siempre es O(n2)
void burbujaMejorado(int *arreglo, int n)
{
int aux,i,j,bandera;
for(i=0;i<n-1;i++){
bandera=0;
for(j=0;j<n-i-1;j++){
if(arreglo[j] > arreglo[j+1]){
aux=arreglo[j];
arreglo[j]=arreglo[j+1];
arreglo[j+1]=aux;
bandera=1;
}
}
if(bandera==0) break; //Si no hubo intercambios, terminar…
}
}
1.3 SORT DE SELECCIÓN
A continuación se presenta el código en C++ del sort de selección:
void select(int *arreglo, int n)
{
Contador
int minj, minx;
1
for(int i=0; i<n-1; i++)
{
minj=i;
minx=arreglo[i];
(n-1)+1
(n-1)
(n-1)
for(int j=i+1; j<n; j++)
{
if(arreglo[j]<minx)
{
minj=j;
minx=arreglo[j];
}
}
arreglo[minj]=arreglo[i];
arreglo[i]=minx;
}
}
(n2-n)/2 + (n-1)
(n2-n)/2
(n2-n)/2
(n2-n)/2
(n2-n)/2
(n2-n)/2
(n-1)
(n-1)
(n-1)
-----------------------7(n-1) + 6((n2-n)/2) + 2
Orden: O(n2)
La mayoría del tiempo de ejecución se gasta ejecutando las instrucciones del ciclo for más
interno, el tiempo que toma cada ejecución de este ciclo puede ser delimitada por una
constante a (es decir, decimos que este tiempo de ejecución será máximo a), así que el tiempo
de ejecución total del ciclo mas interno para un valor de i dado será máximo b+a(n-i) donde b
es una constante introducida para tener en cuenta el tiempo de inicialización del ciclo.
El tiempo que toma una vuelta del ciclo exterior está delimitado por c+b+a(n-i), donde c es una
constante introducida para tener en cuenta la el tiempo de inicialización del ciclo exterior y las
asignaciones que se hacen antes del segundo ciclo.
Finalmente, el tiempo que toma el algoritmo completo no es mayor a d+[c+b+a(n-i)] donde la
sumatoria va desde i=1 hasta i=n-1 y la constante d se introduce para tener en cuenta el tiempo
de ejecución de las primeras declaraciones de variables.
Ahora, ¿Cómo podemos simplificar esta ecuación para obtener una ecuación de orden lo más
simple posible? Observando detenidamente, se puede ver que d+[c+b+a(n-i)] se puede
escribir como:
d + c(n-1) + b(n-1) + a(n-1) + a(n-2) … + a(n-(n-1)) el último término se puede reducir:
d + c(n-1) + b(n-1) + a(n-1) + a(n-2) … + a
términos:
Sacando factor común a y reorganizando lo
d + c(n-1) + b(n-1) + a[ 1 + … + (n-2) + (n-1) ] La expresión entre corchetes corresponde a la
suma Gaussiana, desde 1 hasta n-1, que puede expresarse como:
1 + … + (n-2) + (n-1) = (n-1)(n)/2 Reemplazando este resultado en la fórmula anterior:
d + c(n-1) + b(n-1) + a(n2 – n)/2 Efectuando los productos obtenemos:
d + cn - c + bn – b + an2/2 – an/2 Sacando factores comunes n:
an2/2 + n( b + c –a/2 ) + (d –c –b)
De esta ecuación se concluye, con ayuda de las reglas teóricas que nos dicen que el orden de
un polinomio es nk donde k es el grado del polinomio, que el algoritmo sort por selección es de
orden cuadrático. O(n2)
1.4SORT DE INSERCIÓN
Otro de los múltiples métodos de ordenación que existen es el sort de inserción, que se
presenta a continuación:
void sortInsercion( int v[], int n )
{
int x, j;
Op. 1
Op. 2
Op. 3
Op. 4
for(int i=1; i<n; i++)
{
x=v[i];
j=i-1;
while( (j>=0)&&(v[j]>x) )
{
v[j+1]=v[j];
j=j-1;
}
v[j+1]=x;
}
}
Contador
1
(n-1)+1
(n-1)
(n-1)
(n2-n)/2 + (n-1)
(n2-n)/2
(n2-n)/2
(n2-n)/2
(n-1)
(n-1)
-----------------------6(n-1) + 4((n2-n)/2)+ 2
Orden: O(n2)
Es conveniente analizar cómo funciona este algoritmo: para cada índice i se guarda en la
variable auxiliar x el elemento v[i] y se comienzan a desplazar todos los elementos de índice
inferior que sean de valor mayor que el v[i] original (guardado en x), cuando se encuentra un
elemento de valor menor o igual que x se guarda x en el hueco libre. En términos más
generales, se puede decir que este algoritmo busca el lugar apropiado para cada elemento y lo
inserta allí. La mejor forma de comprender como funciona es aplicarlo a un arreglo sencillo y
seguirlo paso a paso.
Para hallar el orden del sort de selección tomaremos como tamaño del problema el número de
elementos que contiene el vector a ordenar (n).
El bucle más externo (for) se repite n veces, por tanto, la función que indica el número de veces
que iterará este ciclo es claramente n, que obviamente, es de orden O(n).
Dentro de este ciclo se tienen cuatro operaciones, de las cuales tres son de orden constante
(op. 1, 2, 4) y una es un ciclo while (op. 3). Para analizar el orden del ciclo while hayamos el
número de veces que se ejecuta: En el peor de los casos, este ciclo interno se ejecutará j
veces y como el máximo valor que tomará j está dado por n, podemos decir que el orden de
este ciclo interno es O(n). Las operaciones internas de este ciclo son de orden constante, por
tanto el orden total del while es O(n).
El orden total de la parte interna del for, es el máximo orden de las operaciones 1, 2, 3, 4.
Como los órdenes de 1, 2 y 4 son O(1) y el orden de 3 es O(n), el orden total de la parte interna
del for es O(n).
Finalmente, el orden del algoritmo es O(n*n) = n2 en el peor de los casos. Sin embargo, este
algoritmo tiene un orden menor si el vector ya estaba parcialmente ordenado, y si el vector
estaba totalmente ordenado, llega a tener un orden lineal (ya que en ese caso el while se
ejecuta una sola vez).
ANEXOS
A REFERENCIAS
Joyanes Aguilar, Luis & Zahonero Martínez, Ignacio. "Estructura de Datos". McGraw Hill.1998
B TALLER
Crear un algoritmo que calcule el n-ésimo término de la serie de Fibonacci y calcular su orden.
C CREDITOS
Editor: PhD. Fernando Arango
Colaboradores: Ing. Edwin Hincapie, Ms.C Francisco Moreno, Santiago Londoño, Alberto
Jiménez, Juan Carlos Hernández, Carlos Andrés Giraldo, Diego Figueroa.
Descargar