Ordenamientos

Anuncio
Estructuras de datos
Estructuras de datos
Introducción
Básicos
Los ordenamientos son una tarea
frecuente y fundamental en la
programación de sistemas.
! Grandes cantidades de datos se
almacenan para su posterior consulta.
! Las búsquedas más eficientes se basan
en conjuntos de datos ordenados.
!
Ing.
Ordenamientos
Ing.Jorge
JorgeA.
A.Hernández
HernándezP.:
P.:Ordenamientos
! Los
tres métodos básicos son:
Burbuja
– Inserción
– Selección
–
Ing.
Ordenamientos
Ing.Jorge
JorgeA.
A.Hernández
HernándezP.:
P.:Ordenamientos
Estructuras de datos
Estructuras de datos
Básicos
Básicos
template <class T>
void burbuja(T *a, int tam){
int i, j;
for( i = 0; i < tam; i ++) //n pasadas
for( j = tam-1; j >= i + 1; j--) //n comparaciones
if(a[j-1] > a[j]) intercambia(a, j-1, j);
}
Ing.
Ordenamientos
Ing.Jorge
JorgeA.
A.Hernández
HernándezP.:
P.:Ordenamientos
template <class T>
void intercambia(T *a, int i, int j){
T temp;
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
Ing.
Ordenamientos
Ing.Jorge
JorgeA.
A.Hernández
HernándezP.:
P.:Ordenamientos
1
Estructuras de datos
Estructuras de datos
Básicos
Básicos
template <class T>
void insercion(T *a, int tam){
int i, j; T v;
for( i = 0; i < tam; i ++){
v = a[i]; //elemento a insertar
for( j = i; j > 0; j--){
if(a[j-1] <= v) break; //los j menores ya estan ordenados
a[j] = a[j-1]; //recorrer los mayores para hacer la inserción
}
a[j] = v; //insertar el elemento
}
}
template <class T>
void seleccion(T *a, int tam){
int i, j;
for( i = 0; i < tam-1; i ++)
for( j = i + 1; j < tam; j++)
if(a[i] > a[j]) intercambia(a, i, j); //busca el
//elemento menor en el resto no ordenado
}
Ing.
Ordenamientos
Ing.Jorge
JorgeA.
A.Hernández
HernándezP.:
P.:Ordenamientos
Ing.
Ordenamientos
Ing.Jorge
JorgeA.
A.Hernández
HernándezP.:
P.:Ordenamientos
!
!
!
Estructuras de datos
Estructuras de datos
Básicos
Básicos
Todos los métodos de ordenamiento pueden
describirse en términos de comparaciones e
intercambios.
Los tres métodos básicos tienen un
rendimiento cuadrático para el peor de los
casos en cuanto al número de comparaciones.
El peor caso es una lista en orden inverso.
Ing.
Ordenamientos
Ing.Jorge
JorgeA.
A.Hernández
HernándezP.:
P.:Ordenamientos
!
!
El método de la burbuja puede mejorarse con
la ayuda de un centinela que verifique si se
han realizado intercambios en alguna pasada
intermedia.
Una técnica útil en la selección consiste en
guardar la posición del elemento menor y
hacer un solo intercambio al final de la pasada.
Ing.
Ordenamientos
Ing.Jorge
JorgeA.
A.Hernández
HernándezP.:
P.:Ordenamientos
2
!
!
Estructuras de datos
Estructuras de datos
Shellsort
Shellsort
Métodos más elaborados usan la técnica de
divide y venceras para lograr reducir el tiempo
de ordenamiento.
El más simple de estos métodos es el
shellsort. Básicamente aprovecha que el
ordenamiento por inserción mejora su
eficiencia con arreglos parcialmente
ordenados.
Ing.
Ordenamientos
Ing.Jorge
JorgeA.
A.Hernández
HernándezP.:
P.:Ordenamientos
!
!
!
!
template <class T>
void shellsort(T *a, int tam){
int i, j, h; T v;
for(h = 1; h <= tam/9; h = h*3 + 1); //generador de secuencias(1, 4, 13, 40, 121, 364…)
for( ; h >0; h /= 3) //controla los h-ordenamientos
for( i = h; i < tam; i ++){ //ordenamiento por inserción
v = a[i];
for( j = i ; j >= h; j-=h){
if(a[j - h] <= v) break;
a[j] = a[j-h];
}
a[j] = v;
}
}
Ing.
Ordenamientos
Ing.Jorge
JorgeA.
A.Hernández
HernándezP.:
P.:Ordenamientos
Estructuras de datos
Estructuras de datos
Shellsort
Mergesort
Sus puntos a resaltar son la secuencia de
preordenamientos a distancias h.
Dicha secuencia es empírica y se sabe que el
método es dependiente de la misma. La peor
secuencia conocida es aquella de potencias de
2.
Todas las secuencias deben terminar en 1.
Su rendimiento es aprox. O(N1.25).
Ing.
Ordenamientos
Ing.Jorge
JorgeA.
A.Hernández
HernándezP.:
P.:Ordenamientos
!
!
!
Otro método muy simple que usa la técnica de
divide y vencerás es el ordenamiento por
fusión o mergesort.
Se basa en fusionar dos subarreglos ya
ordenados en uno mayor.
Se ordena eligiendo al menor elemento de los
dos subarreglos hasta que ambos quedan
vacios.
Ing.
Ordenamientos
Ing.Jorge
JorgeA.
A.Hernández
HernándezP.:
P.:Ordenamientos
3
!
!
Estructuras de datos
Estructuras de datos
Mergesort
Mergesort
El método de particionamiento es binario.
Divide el arreglo y subarreglos a la mitad cada
vez, deteniéndose en subarreglos de tamaño
uno.
Los arreglos de tamaño uno ya estan
ordenados. A partir de ellos se comienza la
fusión creando arreglos ordenados que se
acercan en tamaño al arreglo original.
Ing.
Ordenamientos
Ing.Jorge
JorgeA.
A.Hernández
HernándezP.:
P.:Ordenamientos
!
Sus incovenientes son:
–
–
!
uso de un arreglo auxiliar
su naturaleza recursiva.
La implementación de dicho algoritmo tiene
una eficiencia temporal de O(NlogN).
Ing.
Ordenamientos
Ing.Jorge
JorgeA.
A.Hernández
HernándezP.:
P.:Ordenamientos
Estructuras de datos
Estructuras de datos
Mergesort
Fusión externa
template <class T>
void mergesort(T *a; int izq; int der){
int i, j, k, m; T b[tam];
if( der > izq){ //mas de un elemento
m = (izq + der) / 2;
mergesort(a, izq, m); //mitad izquierda
mergesort(a, m+1, der); //mitad derecha
for(i = izq; i <= der; i++) b[i] = a[i]; //copia mitades a fusionar
for(i = izq, j = izq, k = m+1; i <= der; i++) // fusionar ambas mitades
if( j <= m && k <= der) //elegir al menor de los dos
a[i] = (b[j] < b[k]) ? b[j++] : b[k++];
else //uno de los arreglos ya esta vacio
a[i] = (k > der) ? b[j++] : b[k++];
}
}
Ing.
Ordenamientos
Ing.Jorge
JorgeA.
A.Hernández
HernándezP.:
P.:Ordenamientos
!
!
El ordenamiento por fusión puede extenderse
a ordenar datos en memoria secundaria.
El problema del ordenamiento externo consiste
en los siguientes puntos:
–
–
El acceso al medio es lento y a veces secuencial.
La memoria secundaria es mucho mayor a la
memoria principal.
Ing.
Ordenamientos
Ing.Jorge
JorgeA.
A.Hernández
HernándezP.:
P.:Ordenamientos
4
Estructuras de datos
Estructuras de datos
Fusión externa
Fusión externa
La técnica más recomendada consiste
en usar la fusión multivias.
! Consiste en dividir el archivo en partes
que se puedan ordenar en memoria
interna para luego fusionarlas.
!
!
!
!
!
!
Ing.
Ordenamientos
Ing.Jorge
JorgeA.
A.Hernández
HernándezP.:
P.:Ordenamientos
!
!
Considere el siguiente ejemplo.
Se tiene espacio en memoria para almacenar
solo tres registros.
Se usarán tres vías o subarchivos para hacer
la fusión.
Se dispone de un archivo de entrada con 25
registros. EJEMPLODEORDENACIONFUSION.
Cada carácter representa un registro.
Ing.
Ordenamientos
Ing.Jorge
JorgeA.
A.Hernández
HernándezP.:
P.:Ordenamientos
Estructuras de datos
Estructuras de datos
Fusión externa
Fusión externa
Leer las tres primeras letras EJE y ordenar
EEJ, escribirlas en la cinta 1. Tomar las
siguientes 3 ordenar y escribirlos en la cinta 2.
Los siguientes 3 repetir el proceso con las
cintas 3, 1, 2, ...etc hasta vaciar el archivo
original.
En la siguiente lámina se muestra el resultado
de la primera pasada.
Ing.
Ordenamientos
Ing.Jorge
JorgeA.
A.Hernández
HernándezP.:
P.:Ordenamientos
Cinta 1 EEJ-DOR-FNU
Cinta 2 LMP-AEN-IOS
Cinta 3 DEO-CIO-N
Cinta 4
Cinta 5
Cinta 6
A este proceso seguiría el de la fusión con
subarchivos de tamaño 3.
Ing.
Ordenamientos
Ing.Jorge
JorgeA.
A.Hernández
HernándezP.:
P.:Ordenamientos
5
Estructuras de datos
Estructuras de datos
Fusión externa
Fusión externa
El resultado de la segunda pasada sobre el archivo a
ordenar sería como sigue:
Cinta 1
Cinta 2
Cinta 3
Cinta 4 DEEEJLMOPCinta 5 ACDEINOORCinta 6 FINNOSUA este proceso seguiría el de la fusión con subarchivos de
tamaño 9. Este ejemplo concluiría a la tercer pasada.
Ing.
Ordenamientos
Ing.Jorge
JorgeA.
A.Hernández
HernándezP.:
P.:Ordenamientos
!
!
!
!
!
Se nota el inconveniente de tener que usar 3
subarchivos más para realizar la fusión.
El proceso puede mejorarse si se usan
montículos para realizar la fusión en lugar de
una selección simple.
Pueden usarse cualquier número permitido de
vías tomando en cuenta que se necesitarán el
doble de archivos temporales.
Ing.
Ordenamientos
Ing.Jorge
JorgeA.
A.Hernández
HernándezP.:
P.:Ordenamientos
Estructuras de datos
Estructuras de datos
Heapsort
Heapsort
Otro de los métodos clásicos de ordenamiento
es el ordenamiento por montículos o heapsort.
Utiliza la estructura de montículos
aprovechando que su implementación basada
en árboles binarios tiene una eficiencia
logarítmica para la mayoría de sus
operaciones.
Ing.
Ordenamientos
Ing.Jorge
JorgeA.
A.Hernández
HernándezP.:
P.:Ordenamientos
1
2
4
5
9
8
5
7
6
3
6
3
2
7
9 8 7 5 6 3 2
Un heap descendente y su representación por medio de
un arreglo.
Ing.
Ordenamientos
Ing.Jorge
JorgeA.
A.Hernández
HernándezP.:
P.:Ordenamientos
6
!
!
!
!
Estructuras de datos
Estructuras de datos
Heapsort
Heapsort
Nótese que los hijos son menores a su padre en un
heap descendente.
Los numeros fuera de los círculos lo relacionan con las
posiciones del arreglo.
Nótese también que un padre esta a la mitad del
arreglo con respecto a sus hijos.
Esto último hace las operaciones de tiempo
logarítmico cuando es necesario hacer intercambios.
Ing.
Ordenamientos
Ing.Jorge
JorgeA.
A.Hernández
HernándezP.:
P.:Ordenamientos
template <class T>
void subirmonticulo(int k){
T v;
v = a[k];
while(a[(k-1)/2] <= v ){
a[k] = a[(k-1)/2]; //sustituir por el padre
k = (k-1)/2;
if ( k < 1) break; // no sobrepasar el índice 0
}
a[k] = v; //acomodar en el lugar correcto
}
Ing.
Ordenamientos
Ing.Jorge
JorgeA.
A.Hernández
HernándezP.:
P.:Ordenamientos
Estructuras de datos
Estructuras de datos
Heapsort
Heapsort
void insertar(T v){
if(ult < TAM){ //no sobrepasar el final del arreglo
a[ult++] = v; //considerar que la primera vez ult = 0
subirmonticulo(ult-1);
}
}
T suprimir(){
T v = a[0]; //eliminar el más grade
a[0] = a[--ult]; //sustituirlo por el ultimo del montículo
bajarmonticulo(0); //restablecer el montículo
return v;
}
Ing.
Ordenamientos
Ing.Jorge
JorgeA.
A.Hernández
HernándezP.:
P.:Ordenamientos
template <class T>
void bajarmonticulo(int k){
T v = a[k]; //guardar elemento a mover
while(k <= (ult-1)/2){ //un nivel antes de las hojas
j = 2*k + 1; //hijo izquierdo de k (si k inicia en 0)
if(j < (ult-1)) //k tiene mas de un hijo
if(a[j] < a[j+1]) j++; //el hijo derecho es mayor
if(v >= a[j]) break; //se llego al final del montículo
a[k] = a[j]; //sustituir por el mayor de los hijos
k = j;
}
a[k] = v; //colocar en el lugar correcto
}
Ing.
Ordenamientos
Ing.Jorge
JorgeA.
A.Hernández
HernándezP.:
P.:Ordenamientos
7
Estructuras de datos
Estructuras de datos
Heapsort
Heapsort
Las operaciones subir y bajar montículo
estan diseñadas para restablecer el
montículo.
! Dichas operaciones usan recorridos del
montículo de padres a hijos o viceversa.
! Estos recorridos son de tiempo
logarítmico.
!
Ing.
Ordenamientos
Ing.Jorge
JorgeA.
A.Hernández
HernándezP.:
P.:Ordenamientos
!
Un ordenamiento simple usaría las
operaciones insertar y suprimir.
template <class T>
void heapsort(T *b, int tam){ //ordena arreglo de tamaño tam
int i;
crearmonticulo(tam); //crea un montículo de tamaño tam
for( i = 0; i < tam; i++) insertar(b[i]); //inserta en un montículo
for(i = tam – 1; i >= 0; i--) b[i] = suprimir(); //suprime en orden inverso
}
Ing.
Ordenamientos
Ing.Jorge
JorgeA.
A.Hernández
HernándezP.:
P.:Ordenamientos
Estructuras de datos
Estructuras de datos
Heapsort
Heapsort
template <class T>
void heapsort(T *a, int tam){
int k;
for( k = (tam-1)/2; k >= 0; k --) //no considerar los montículos de tam
1
bajarmonticulo(a, tam, k); //construir el montículo
ult = tam; //señala la última posición del arreglo
while(ult > 0){
intercambio(a, 0, ult-1); //poner el mayor al último
bajarmonticulo(a, --ult, 0); //restablece sin considerar al último
} //elemento del arreglo (ya quedo en su lugar)
}
Ing.
Ordenamientos
Ing.Jorge
JorgeA.
A.Hernández
HernándezP.:
P.:Ordenamientos
La eficiencia del heapsort esta entre
2NlogN y 1.5NlogN.
! En la segunda implementación se mejora
la eficiencia temporal y espacial.
! Es un buen método que aprovecha las
virtudes de los montículos.
!
Ing.
Ordenamientos
Ing.Jorge
JorgeA.
A.Hernández
HernándezP.:
P.:Ordenamientos
8
!
!
!
Estructuras de datos
Estructuras de datos
Quicksort
Quicksort
Sin lugar a dudas el más estudiado y
comentado de los métodos de ordenamiento
es el ordenamiento rápido o quicksort.
Este aprovecha la técnica de divide y vencerás
además de una selección doble.
Usa un pivote para realizar las particiones y
colocar los menores antes del pivote y los
mayores después.
Ing.
Ordenamientos
Ing.Jorge
JorgeA.
A.Hernández
HernándezP.:
P.:Ordenamientos
!
!
!
Este método además es capaz de localizar la
posición exacta de un elemento.
Su único punto débil es que no puede detectar
que un arreglo o subarreglo ya fue ordenado.
Esto último da pie a mejoras. Una de ellas
consiste en trabajar combinado con un método
de inserción a partir de subarreglos.
Ing.
Ordenamientos
Ing.Jorge
JorgeA.
A.Hernández
HernándezP.:
P.:Ordenamientos
Estructuras de datos
Estructuras de datos
Quicksort
Quicksort
template <class T>
void quicksort(Arreglo<T> &a, int izq, int der){
int i, j;
T v, temp;
if( der > izq){
v = a[der]; //usar como pivote el extremo derecho de la partición
for(i = izq-1, j = der; ; ){
while(a[++i] < v ); //buscar la posición del pivote
while(a[--j] > v && j > 0);
if( j <= i) break; //ya se encontro la posicion del pivote
intercambio(a, i, j); //menores a la izquierda y mayores a la derecha
}
intercambio(a, i, der); //mover el pivote a su posición
quicksort(a, izq, i-1); //ordenar elementos a la izquierda del pivote
quicksort(a, i+1, der); //ordenar elementos a la derecha del pivote
}
}
Ing.
Ordenamientos
Ing.Jorge
JorgeA.
A.Hernández
HernándezP.:
P.:Ordenamientos
template <class T>
void selecc(T *a, int tam, int k){
int i, j, izq, der; T v;
izq = 0; der = tam –1;
while(der > izq){
for(i = izq-1, j = der, v = a[der]; ; ){ //crear particiones
while(a[++i] < v);
while(a[--j] < v && j > 0);
if ( i >= j) break;
intercambio(a, i, j);
}
intercambio(a, i, der); //mover pivote a su posición
if( i >= k) der = i – 1; //restringir el espacio de búsqueda
if(i <= k) izq = i +1;
}
}
Ing.
Ordenamientos
Ing.Jorge
JorgeA.
A.Hernández
HernándezP.:
P.:Ordenamientos
9
Estructuras de datos
Otros métodos
!
Existen otros métodos dignos de mención
como:
–
–
!
Ordenamiento por urnas o binsort.
Ordenamiento por residuos o radixsort.
También pueden usarse métodos de ordenamiento
indirecto por medio de un arreglo de apuntadores
que minimicen los intercambios de registros.
Ing.
Ordenamientos
Ing.Jorge
JorgeA.
A.Hernández
HernándezP.:
P.:Ordenamientos
10
Descargar