Ordenamiento

Anuncio
Universidad Técnica Federico Santa María - Departamento de Informática
Universidad Técnica Federico Santa María - Departamento de Informática
¿Qué es ordenamiento?
Ordenamiento
• Es la operación de arreglar los registros de una tabla en algún
orden de acuerdo a algún criterio.
• El propósito principal de un ordenamiento es el de facilitar la
búsqueda.
• Ejemplos : Guía telefónica, tablas de contenido, bibliotecas y
diccionarios, etc.
Mauricio Solar
Lorna Figueroa
2008
Universidad Técnica Federico Santa María - Departamento de Informática
Ordenamiento
• Importancia de mantener orden de datos: Fácil y rápido acceso
de los datos.
• Criterio para el análisis de un algoritmo:
• factores con respecto a qué se desea optimizar:
• Espacio de memoria
• Tiempo de ejecución
Universidad Técnica Federico Santa María - Departamento de Informática
Ordenamiento
• Al momento de tomar esta decisión se debe investigar:
• Con qué equipo de trabajo se cuenta (donde se ejecuta
el programa),
• Necesidades del cliente (si debe ser rápido porque se
atiende a diario muchas personas),
• etc.
Universidad Técnica Federico Santa María - Departamento de Informática
¿Qué es ordenamiento?
• Formalmente: Dado un conjunto de n elementos a1, a2,..., an y
una relación de orden total (≤) sobre ellos, el problema del
ordenamiento consiste en encontrar una permutación de esos
elementos ordenada de forma creciente/decreciente.
• El tipo y tamaño de los elementos, así como el dispositivo en
donde se encuentran almacenados pueden influir en el método
utilizado para ordenarlos.
Universidad Técnica Federico Santa María - Departamento de Informática
¿Qué es ordenamiento?
• Distintos criterios para clasificar los
posibilidad es respecto a su eficiencia:
• Θ(n2): Burbuja, Inserción, Selección.
• Θ(nlogn): Mezcla, Montículos, Quicksort.
• Otros:
• Incrementos Θ(n1.25),
• Cubetas Θ(n),
• Residuos Θ(n).
algoritmos,
una
Universidad Técnica Federico Santa María - Departamento de Informática
Universidad Técnica Federico Santa María - Departamento de Informática
Taxonomía de los algoritmos - internos
Tipos de Ordenamiento
• Interno : datos a ordenar están localizados en la memoria
principal del computador.
Î se asume que el tiempo que se requiere para acceder
cualquier elemento es el mismo.
• Externo : datos a ordenar están localizados en algún
dispositivo externo (disco, cinta, cilindro magnético, etc),
Î se asume que el tiempo que se requiere para acceder a
cualquier elemento depende de la última posición
accesada.
•
Ordenamiento por intercalación
1.- Concatenación directa.
2.- Concatenación merge.
•
Ordenamiento por calculo de direcciones
1.- Ordenamiento de llaves por calculo de direcciones.
Universidad Técnica Federico Santa María - Departamento de Informática
Universidad Técnica Federico Santa María - Departamento de Informática
Taxonomía de los algoritmos - internos
•
Ordenamiento por intercambio
1.2.3.4.-
•
Burbuja.
Transposición par e impar.
Shaker sort (vibración).
Quick sort (rápido).
Taxonomía de los algoritmos - externos
•
•
•
•
•
Straight merging.
Natural merging.
Balanced multiway merging.
Polyphase sort.
Distribution of initial runs.
Ordenamiento por selección
1.- Selección directa.
2.- Heap sort.
Universidad Técnica Federico Santa María - Departamento de Informática
Universidad Técnica Federico Santa María - Departamento de Informática
Algoritmos de intercambio
Taxonomía de los algoritmos - internos
•
•
Ordenamiento por inserción
1.- Inserción directa.
2.- Inserción binaria.
3.- Shell.
Ordenamiento por distribución
1.- Base radix.
2.- Conteo.
• Los elementos se toman de dos en dos, se comparan y se
intercambian si no están en el orden adecuado.
• Este proceso se repite hasta que se ha analizado todo el
conjunto de elementos y ya no hay intercambios.
•
•
•
•
Burbuja.
Transposición par e impar.
Shaker sort (vibración).
Quick sort (rápido).
Universidad Técnica Federico Santa María - Departamento de Informática
Algoritmos de selección
• Se selecciona o se busca el elemento más pequeño (o más
grande) de todo el conjunto de elementos y se coloca en su
posición adecuada.
• Este proceso se repite para el resto de los elementos hasta que
todos son analizados.
• Selección directa
• Heap sort
Universidad Técnica Federico Santa María - Departamento de Informática
Algoritmos de inserción
• Los elementos que van a ser ordenados son considerados uno a
la vez.
• Cada elemento es insertado en la posición apropiada con
respecto al resto de los elementos ya ordenados.
•
•
•
•
Inserción directa,
Shell,
Inserción binaria,
Hashing
Universidad Técnica Federico Santa María - Departamento de Informática
Algoritmos de enumeración
• Cada elemento es comparado con los demás.
• En la comparación se cuenta cuántos elementos son más
pequeños que el elemento que se está analizando, generando así
una enumeración.
• El número generado para cada elemento indicará su posición.
Universidad Técnica Federico Santa María - Departamento de Informática
Taxonomía de los algoritmos
• Los métodos simples son:
• Inserción (o por inserción directa), selección, burbuja y
shell, en dónde el último es una extensión al método de
inserción, siendo más rápido.
• Los métodos más complejos son:
• quick-sort (ordenación rápida) y el heap sort.
Universidad Técnica Federico Santa María - Departamento de Informática
Algoritmos de Intercambio: Burbuja
• Pasa por un archivo en forma secuencial varias veces.
• Cada paso consiste en comparar un elemento del archivo con su
sucesor (x[j] con x[j+i]), e intercambiar los dos elementos si no
están en el orden apropiado.
• Este algoritmo es de fácil comprensión y programación pero es
de los menos eficientes
• n-1 pasos y n-i comprobaciones en cada paso.
Universidad Técnica Federico Santa María - Departamento de Informática
Algoritmos de Intercambio: Burbuja
• Recorre el arreglo intercambiando los elementos adyacentes que
estén desordenados.
• Se recorre el arreglo hasta que ya no haya cambios.
• toma el elemento mayor y lo va recorriendo de posición en
posición hasta ponerlo en su lugar.
paso 1: [ Inicializar i al final de arreglo ]
for(i = n; i ≥ 1; i--)
paso 2: [ Inicializar j desde la segunda posición ] for(j = 2; j ≥ i; j++)
paso 3: [ Si a[j-1] es mayor que el que le sigue ]
if a[j-1]< a[j]
paso 5:
[ Los intercambia ]
swap(a,j-1,j);
paso 6: [ Fin ]
Universidad Técnica Federico Santa María - Departamento de Informática
Burbuja - implementación
void Burbuja ( vector a; int prim, ult) {
int i, j;
for ( i = prim; i <= ult-1; i++ ) {
for ( j = ult; j <= i+1; j-- ) {
if ( a[j-1]>a[j] )
swap ( a, j-1, j );
}
}
}
}
Universidad Técnica Federico Santa María - Departamento de Informática
Burbuja - implementación
void burbuja() {
int aux; Boolean b = true; byte i = 1, j;
while ( (i <= n-1) && (b) ) {
b = false;
while ((j< n-1) && (b)) {
b = false;
for (j = 1; j <= n-1; j++) {
if (x[j] > [j+1]) {
b = true;
aux = x[j];
x[j] = x[j+1];
x[j+1] = aux;
}
}
i++;
}
}
Universidad Técnica Federico Santa María - Departamento de Informática
Algoritmos de Intercambio: Burbuja
• En el peor de los casos, el número máximo de revisiones es n-1 y
el número de intercambios o comparaciones está dado por
(n-1) * (n-1) = n2 - 2n + 1
• En el mejor de los casos, el número de revisiones es mínimo 1 y
el ciclo de comparaciones es n-1
• El algoritmo es O(n) en el mejor de los casos y O(n2) en el
peor de los casos.
• Ventaja: requiere poco espacio adicional
• una posición de memoria para el valor para intercambio
• Desventaja: utilizar excesivo tiempo de ordenamiento por el
número de comparaciones que realiza.
Universidad Técnica Federico Santa María - Departamento de Informática
Algoritmos de Intercambio: Burbuja
• Es de complejidad cuadrática.
• Es el peor entre los algoritmos de O(n2): Selección, Inserción y
Burbuja, no sólo en cuanto al tiempo de ejecución, sino también
respecto al número de comparaciones y de intercambios que
realiza.
• Una posible mejora que puede admitir este algoritmo es el
control de la existencia de una pasada sin intercambios; en ese
momento el vector estará ordenado.
• Mejora: Utilizar una bandera booleana que cambia cuando se
realiza algún intercambio,
• Permanece sin cambio cuando no cambia ningún valor,
• puede truncar el ciclo y terminar el proceso de
ordenamiento.
Universidad Técnica Federico Santa María - Departamento de Informática
Burbuja - ejemplo
1
2
3
4
n =
b =
i =
j =
x =
aux
[20] 10
[10] 20
[40] 40
[30] 30
4 ( n-1 = 3
t, f, t, t,
1, 2, 3
1, 2, 3
2, 3
= 20, 40
10
20
30
40
)
f
Universidad Técnica Federico Santa María - Departamento de Informática
Algoritmos de Intercambio: Par_impar
void par_impar( ) {
int r, i, j, aux;
r = (n+1)/2;
for ( j = 1; j <= r; ) {
i = 1;
while (i<n) {
if ( x[i] > x[i+1] ) {
aux = x[i];
x[i] = x[i+1];
x[i+1] = aux;
i = i+2;
}
else
i = i+2;
}
}
}
i = 2;
while ( i < n ) {
if ( x[i] > x[i+1] )
aux = x[i];
x[i] = x[i+1];
x[i+1] = aux;
i = i+2;
}
else
i = i+2;
}
{
Universidad Técnica Federico Santa María - Departamento de Informática
Universidad Técnica Federico Santa María - Departamento de Informática
Algoritmos de Intercambio: Par_impar
1
2
3
4
5
6
[40]
[30]
[10]
[60]
[20]
[50]
30
40
10
60
20
50
30
10
40
60
20
50
30
10
40
20
60
50
10
30
40
20
60
50
10
30
20
40
60
50
10
30
20
40
50
50
10
20
30
40
50
60
n = 6
r = 3
j = 1,2,3.
i =1,3,5,7,2,4,6,1,3,5,7,2,4,6,1,3,5,7,2,4,6
aux = 40,40,60,30,40,60,30
Universidad Técnica Federico Santa María - Departamento de Informática
Algoritmos de Intercambio: shaker
•
•
La idea básica de este algoritmo consiste en mezclar las dos
formas en que se puede realizar el método de la burbuja.
En este algoritmo cada pasada tiene dos etapas.
1. En la primera etapa "de derecha a izquierda“:
• Se trasladan los elementos más pequeños hacia la parte
izquierda del arreglo, almacenando en una variable la
posición del último elemento intercambiado.
• Las sucesivas pasadas trabajan con los componentes del
arreglo comprendidos entre las posiciones almacenadas
en las variables.
• El tamaño de la variable que almacena el extremo
izquierdo del arreglo es mayor que el contenido de la
variable que almacena el extremo derecho.
Universidad Técnica Federico Santa María - Departamento de Informática
Algoritmos de Intercambio: shaker
void shakersort ( ) {
int aux,k,i,r,j; i = 2; r = n;
do
for ( j = r; j >= i; j--) {
if (x[j-1] > x[j]) {
aux = x[j-1];
x[j-1] = x[j];
x[j] = aux;
k =j;
}
}
i = k+1;
k = n;
for ( j = i; j <= r; ) {
if ( x[j-1] > x[j] ) {
aux = x[j-1];
x[j-1] = x[j];
x[j] = aux;
k = j;
}
}
r = k-1;
while ( i > r );
}
Algoritmos de Intercambio: shaker
1
2
3
4
[38]
[12]
[56]
[23]
i =
r =
k =
j =
aux
38
12
23
56
12
38
23
56
12
23
38
56
2,3
4,2
4,2,3
4,3,2,3,4
= 56,38,38
Universidad Técnica Federico Santa María - Departamento de Informática
Algoritmos de Intercambio: Quick Sort
void quick_sort (int a[ ],int p, int q) {
int r;
int contador = 1;
if (p < q) {
contador ++;
r = particion(a,p,q);
quick_sort(a,p,r);
quick_sort(a,r+1,q);
}
}
Universidad Técnica Federico Santa María - Departamento de Informática
int particion(int a[ ],int p, int temp q) {
int temp, x = a[p], i = p-1, j = q+1, cont = 3;
while(1) {
j = j-1;
cont+=5;
while( a[j] > x ) {
cont += 2;
j--;
}
i++;
while ( a[i] < x ) {
cont+=2;
i++;
}
if( i < j ) {
cont += 3;
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
else
return j;
}
}
Universidad Técnica Federico Santa María - Departamento de Informática
Algoritmos de Selección:
Selección directa
• Se divide el vector en dos zonas, una ordenada y otra sin ordenar.
Inicialmente la zona ordenada está vacía y coincide con la
posición 1.
• En cada iteración se toma el elemento mínimo de la zona sin
ordenar y lo coloca en la zona ordenada, intercambiándolo con el
elemento siguiente al último de la zona ordenada.
• A continuación aumenta la zona ordenada en un elemento para
incluir el que se acaba de añadir y vuelve a comenzar otra
iteración.
• Para ordenar todo el vector, se debe realizar una iteración por cada
elemento nuevo a colocar en la zona ordenada y en cada iteración
recorrer toda la zona no ordenada del vector para encontrar el
mínimo y ponerlo en la zona ordenada.
Universidad Técnica Federico Santa María - Departamento de Informática
Algoritmos de Selección:
Selección directa
• Encontrar el menor de todos los elementos del arreglo e
intercambiarlo con el que está en la primera posición.
• Luego el segundo más pequeño, y así sucesivamente hasta ordenar
todo el arreglo.
paso 1: [ Para cada posición del arreglo ] for (i=1;i<= n;)
paso 2: [ Inicializar la posición del menor ] { min = i;
paso 3: [ Recorrer todo el arreglo ]
for( j = i+1; j <= n;)
paso 4: [ Si a[ j ] es menor ]
if a[j] < a[min]
paso 5: [ Reasigna el menor ]
min = j;
paso 6: [ Intercambia los datos ]
swap(a,min,j)
paso 7: [ Fin ]
}
Universidad Técnica Federico Santa María - Departamento de Informática
Algoritmos de Selección:
Selección directa
• El arreglo a ordenar es a = [ 'a','s','o','r','t','i','n','g','e','x','a','m','p','l','e' ]
• Se empieza por recorrer el arreglo hasta encontrar el menor elemento. En este
caso el menor elemento es la primera 'a'. No ocurre ningún cambio. Luego se
procede a buscar el siguiente elemento y se encuentra la segunda 'a'. Esta se
intercambia con el dato que está en la segunda posición, la 's', quedando así el
arreglo después de dos recorridos: a = [ 'a','a','o','r','t','i','n','g','e','x','s','m','p','l','e' ].
• El siguiente elemento, el tercero en orden de menor mayor es la primera 'e', la
cual se intercambia con lo que está en la tercera posición, o sea, la 'o'. Le sigue la
segunda 's', la cual es intercambiada con la 'r'. El arreglo ahora se ve de la
siguiente manera:
• a = [ 'a','a','e','e','t','i','n','g','o','x','s','m','p','l','r' ].
• De esta manera se va buscando el elemento que debe ir en la siguiente posición
hasta ordenar todo el arreglo.
Universidad Técnica Federico Santa María - Departamento de Informática
Selección directa - implementación
void Seleccion(vector a; int prim, ult) {
int i;
for ( i=prim; i <= ult-1; i++ ) {
Intercambia(a ,i, PosMinimo (a, i, ult) )
}
}
int PosMinimo(vector a; int i, j ) {
// devuelve la posicion del minimo elemento de a[i..j]
int pmin, k;
pmin = i;
for ( k = i+1; k <= j; k++) {
if ( a[k] < a[pmin] )
pmin = k;
}
return pmin;
}
Universidad Técnica Federico Santa María - Departamento de Informática
Selección directa - ejemplo
• El arreglo a ordenar es:
a = [ 'a', 's', 'o', 'r', 't', 'i', 'n', 'g', 'e', 'x', 'a', 'm', 'p', 'l', 'e' ]
• Se empieza por recorrer el arreglo hasta encontrar el menor
elemento.
• En este caso el menor elemento es la primera 'a'
• No ocurre ningún cambio.
• Luego se procede a buscar el siguiente elemento y se encuentra la
segunda 'a'
• Esta se intercambia con el dato que está en la segunda
posición, la 's', quedando el arreglo después de dos recorridos:
a = [ 'a', 'a', 'o', 'r', 't', 'i', 'n', 'g', 'e', 'x', 's', 'm', 'p', 'l', 'e' ]
Universidad Técnica Federico Santa María - Departamento de Informática
Selección directa - ejemplo
• El siguiente elemento, el tercero en orden de menor mayor es la
primera 'e'
• se intercambia con lo que está en la tercera posición, la 'o'
• Le sigue la segunda 's',
• la cual es intercambiada con la 'r'.
• El arreglo ahora se ve de la siguiente manera:
a = [ 'a', 'a', 'e', 'e', 't', 'i', 'n', 'g', 'o', 'x', 's', 'm', 'p', 'l', 'r' ]
• De esta manera se va buscando el elemento que debe ir en la
siguiente posición hasta ordenar todo el arreglo.
Universidad Técnica Federico Santa María - Departamento de Informática
Universidad Técnica Federico Santa María - Departamento de Informática
Selección directa
• En el primer paso del ordenamiento se efectúan n-1
comparaciones, en el segundo n-2 comparaciones, y así
sucesivamente.
• El total de comparaciones aproximadas, está dado por: n(n-1)/2.
• La relación de ordenamiento es O(n)2 para cualquier estado inicial
de los elementos del arreglo.
• El costo del problema, tanto en el caso peor como en el caso
mejor es: O(n) = n2
• Este método se le conoce por el nombre de "EMPUJE HACIA
ABAJO", y es recomendable para un número pequeño de
elementos.
Algoritmos de Selección: Heapsort
• El vector debe tener estructura de montículo, es decir, un árbol
en el que los hijos de cada nodo son siempre menores que el
padre.
• De esta forma, no se tiene que recorrer toda la zona desordenada
para encontrar el elemento máximo, ya que en este caso la
ordenación se realiza en sentido inverso.
• La estructura en montículo facilita esta búsqueda y la hace del
orden de log(n).
• Por lo tanto el costo final será log(n) para cada elemento que se
quiera colocar en la zona ordenada, es decir:
O(n) = n log(n)
Universidad Técnica Federico Santa María - Departamento de Informática
Universidad Técnica Federico Santa María - Departamento de Informática
Selección directa
• Es de complejidad cuadrática.
• Dado el número de operaciones de comparación e intercambio
que realiza, es el más adecuado para ordenar pocos registros de
gran tamaño.
• Si el tipo base del vector a ordenar no es entero, sino un tipo más
complejo (guías telefónicas, índices de libros, historiales
hospitalarios, etc.) se debe dar mayor importancia al intercambio
de valores que a la comparación entre ellos en la valoración del
algoritmo por el costo que suponen.
• Analizando el número de intercambios que realiza, es de orden
O(n), frente al orden O(n2) de intercambios que presentan los
métodos de Inserción o Burbuja.
Heapsort - ejemplo
• Aplicar HeapSort( ) para ordenar el conjunto de datos,
S = { 25, 15, 20, 3, 5, 10 }
construir el árbol, y numerar los nodos :
25 1
15
2
3
4
5
Universidad Técnica Federico Santa María - Departamento de Informática
25 15 20 3
5 10
1
5
2
3
4
6
10 6
5
Universidad Técnica Federico Santa María - Departamento de Informática
Algoritmos de Selección: Heapsort
• Es un método de ordenamiento por selección.
• Heap: es un árbol binario de altura mínima, en que los nodos del
nivel más bajo están lo más a la izquierda posible.
• La información es almacenada de manera que al recorrer un
camino desde la raíz hacia las hojas, los datos se encuentran en
orden descendente.
• Si se presenta este arreglo resultante como un árbol se observa
que cada elemento es el padre de los elementos z[i], z[i+1]
puesto que es una estructura con un grupo en el cual j ≤ i/2.
• En la segunda parte del procedimiento se realiza el proceso de
ordenamiento en el cual se recorre el árbol de tal forma que el
resultado es una lista ordenada de elementos.
20 3
Heapsort - ejemplo
Verificar la condición de heap
k = 6 ; (k = nº de nodos)
Intercambiar nodo 1 con nodo 6 :
2
4
3
15
5
2
20 3
5
10 1
Resultado :
25 1
10 6
4
15
3
20 3
25 6
5
5
10 15 20 3
5 25
1
5
2
3
4
6
Universidad Técnica Federico Santa María - Departamento de Informática
Universidad Técnica Federico Santa María - Departamento de Informática
Heapsort - ejemplo
Heapsort - ejemplo
Revisar y recuperar condición de heap, si no se cumple, entre los
nodos 1 y 5:
10 1
k = 4; intercambiar los nodos 1 y 4 :
15 1
Resultado:
15 1
15
2
20 3
2 10
5
2
3
4
25 6
5
5
3
4
20 1
4
3
4
15
5
25 6
5
5
3
5
5 25
1
5
25 6
2
3
4
6
3
5
Resultado:
1
5
5
2
2
10 3
25 6
5
5 10 15 20 25
2
15
10 3
4
4
1
2
3
4
5
6
4
Revisar y recuperar condición de heap, si no se cumple, entre
los nodos 1 y 4:
1
10 3
20
10 3
5 15 20 25
1
3
2
4
5
Resultado:
10 1
1
5
15 1
2
5
25 6
20
k = 3; intercambiar los nodos 1 y 3 :
Resultado :
3
3
5
5
25 6
20
5
15
3
15
10 3
Heapsort - ejemplo
Heapsort - ejemplo
4
6
Universidad Técnica Federico Santa María - Departamento de Informática
Universidad Técnica Federico Santa María - Departamento de Informática
15
5
10 1
Resultado :
25 6
20
5
3
4
25 6
20
5
15
2
2
4
3
2
10 3
5 15 10 3 20 25
5
3
1
3
4
3
1
Revisar y recuperar condición de heap, si no se cumple, entre los
nodos 1 y 3 :
5 1
k = 5; intercambiar los nodos 1 y 5 :
15
25 6
20
5
Heapsort - ejemplo
Heapsort - ejemplo
20 1
10 3
Universidad Técnica Federico Santa María - Departamento de Informática
Universidad Técnica Federico Santa María - Departamento de Informática
2
15
4
10 3
20 15 10 3
5
2
10 3
25 6
5
5
Resultado:
2
1
3
20 3
25 6
5
2
10
4
4
3
5
2
3
5
3
3
2
10 3
15
5
20
25 6
4
15
25 6
20
5
25 6
20
15 5 10 3 20 25
1
3
3
4
5
6
5
3 10 15 20 25
1
2
3
4
5
6
6
Universidad Técnica Federico Santa María - Departamento de Informática
Universidad Técnica Federico Santa María - Departamento de Informática
Heapsort - implementación
Heapsort - ejemplo
Revisar y recuperar condición de heap, si no se cumple, entre
los nodos 1 y 2.
5
3
2
4
1
15
10 3
5
20
25 6
5
3 10 15 20 25
1
2
3
4
5
6
void heap_sort(int n; int x[ ] ) {
int i, j, k, y;
for ( k = 2; k <= n; k++ ) {
i = k;
y = x[k];
j = i/2;
while ( j > 0 ) {
if ( y <= x[j] ) {
x[i] = y
x[i] = x[j];
i = j;
j = i/2;
}
}
}
Universidad Técnica Federico Santa María - Departamento de Informática
Universidad Técnica Federico Santa María - Departamento de Informática
Heapsort - implementación
Heapsort - ejemplo
k = 2; intercambiar los nodos 1 y 2 :
5
3
2
4
Resultado :
1
15
10 3
5
2
25 6
20
5
4
1
3
15
10 3
5
25 6
20
3
5 10 15 20 25
1
2
3
4
5
6
Universidad Técnica Federico Santa María - Departamento de Informática
Universidad Técnica Federico Santa María - Departamento de Informática
Heapsort – implementación ver.01
Heapsort - ejemplo
El algoritmo finaliza, y los datos están ordenados
ascendentemente, siguiendo la numeración de los nodos :
3
2
5
1
10 3
3 5 10 15 20 25
1 2 3
4
15
5
20
25 6
for (k= n; k>= 2; k--) {
y = x[k];
x[k] = x[1];
i = 1;
j = 2;
if ( ( x[3] > x[2] ) && ( k-1 > =3 ) ) {
j =3;
while (j < =k-1) {
if ( x[j] < =y ) {
x[i] = y;
x[i] = x[j];
i = j;
j = 2*i;
if ( x[j-1] > x[j] )
j++;
}
}
}
4
5
6
HeapSort( ) {
BuildHeap( );
// construir el heap
for ( k = n ; k > 1 ; k = k – 1 ) {
BuildHeap( ) {
Intercambiar( A[ 1 ], A[ k ] ;
for ( j = n ; j >= 1 ; j -- )
Heapify(1, k - 1) ;
Heapify( j, n)
}
}
}
Heapify(j, k) {
// hace que A[j : k] cumpla con la condición de heap, suponiendo que A[j+1, k]
// la cumple
if ( (A[ j ] tiene algún hijo ) &&
( algún hijo( no es hoja ) de A[ j ] es mayor que él ) ) {
Sea A[ s ] el mayor de los hijos de A[ j ] ;
Intercambiar (A[ j ], A[ s ] ) ;
Heapify(s, k) ;
}
}
Universidad Técnica Federico Santa María - Departamento de Informática
Algoritmos de Selección: Heapsort
• Ordena un conjunto de datos, en tiempo O(n lg n) en el peor
caso.
• Heapify(j, k) toma tiempo O(lg(k-j)
• Equivalentemente, hacer heapify partiendo de un elemento de
altura h, toma tiempo O(h).
• En BuildHeap hay a lo más n / 2i elementos de altura i.
• Si el heap tiene altura total h, el tiempo total ocupado por
buildheap es : ⎛
⎞
⎞ ⎛
o⎜ ∑ i 2ni ⎟ = o⎜ n∑ 2ii ⎟ = O(n )
⎝ 0≤i ≤ h ⎠ ⎝ i ≥ 0 ⎠
• En HeapSort( ), el tiempo total, para el peor caso, es:
⎛
O(n ) + O⎜⎜ ∑ lg
⎝ 2≤ j ≤ n
⎞
j ⎟⎟ = O(n lg n )
⎠
Universidad Técnica Federico Santa María - Departamento de Informática
Algoritmos de Inserción:
Inserción directa
Universidad Técnica Federico Santa María - Departamento de Informática
Inserción directa – Ejemplo
• El arreglo a ordenar es:
a = [ 'a', 's', 'o', 'r', 't', 'i', 'n', 'g', 'e', 'x', 'a', 'm', 'p', 'l', 'e' ]
• El algoritmo recorre el arreglo de izquierda a derecha.
• Primero toma el segundo dato, 's' y lo asigna a v;
• i toma el valor de la posición actual de v.
• Luego compara 's' con lo que hay en la posición j-1, ie, con 'a'.
• Debido a que 's' no es menor que 'a' no sucede nada y avanza i.
• Ahora v toma el valor 'o' y lo compara con 's',
• como es menor, lleva 's' a la posición de la 'o';
• decrementa j, la cual ahora tiene la posición en dónde estaba 's';
Universidad Técnica Federico Santa María - Departamento de Informática
Inserción directa – Ejemplo
• Toma cada elemento del arreglo y lo compara con los que se
encuentran en posiciones anteriores a la de él dentro del arreglo.
• Si el elemento con el que se está comparando es mayor que el
elemento a ordenar,
• se recorre hacia la siguiente posición superior.
• Si no,
• se detiene el proceso de comparación
• el elemento ya está ordenado
• y se coloca en su posición
• es la siguiente a la del último número con el que se
comparó.
• compara a 'o' con a[j-1] , es decir, con 'a'
• Como no es menor que 'a' sale del for y pone la 'o' en la posición
a[j]
• El resultado hasta este punto es el arreglo siguiente:
a = [ 'a', 'o', 's', 'r', .... ]
Universidad Técnica Federico Santa María - Departamento de Informática
Universidad Técnica Federico Santa María - Departamento de Informática
Algoritmos de Inserción:
Inserción directa
• Toma el arreglo de datos a ordenar a[] y modifica las
posiciones de sus elementos hasta dejarlos ordenados de menor
a mayor.
• n representa el número de elementos que contiene a[ ].
paso 1: [Para cada posición del arreglo] for(i = 2; i<= n;i++)
paso 2: [ Inicializar v y j ]
{ v = a[i]; j = i;
paso 3: [ Compara v con los anteriores ]
while(a[j-1]>v) && (j>1)
paso 4: [ Recorre los datos mayores ]
{ a[j] = a[j-1];
paso 5: [ Decrementa j ]
j = j-1; }
paso 5: [ Inserta v en su posición ]
a[j] = v;
• Así se continúa y el resultado final es el arreglo ordenado :
a = [ 'a', 'a', 'e', 'e', 'g', 'i', 'l', 'm', 'n', 'o', 'p', 'r', 's', 't', 'x' ]
Inserción directa
• Si el arreglo inicial está ordenado se hace una comparación en
cada paso, O(n).
• Si los elementos están ordenados en sentido inverso la relación es
O(n)2.
• Número de comparaciones:
• arreglo ordenado: n-1
• arreglo desordenado: (n-1)*(n/2)
• Método muy adecuado para aquellas situaciones en donde se
necesita ordenar un vector que está casi ordenado, como suele
suceder en aquellas aplicaciones de inserción de elementos en
bancos de datos previamente ordenados cuya ordenación total se
realiza periódicamente.
Universidad Técnica Federico Santa María - Departamento de Informática
Inserción directa - implementación
void Insercion (vector a; int prim, ul) {
int i, j, x;
for ( i = prim+1; i <= ult; i++ ) {
x = a[i];
j = i-1;
while ( ( j >= prim ) && (x < a[j] ) ) {
a[j+1] = a[j];
j--;
}
a[j+1] = x;
}
}
Universidad Técnica Federico Santa María - Departamento de Informática
Inserción binaria - implementación
Inserción_binaria( int x[] ) {
int a, i, j,m, s, r;
for ( i = 2; i <= n; ) {
a = x[i];
s = 1;
r = i;
while (s < r) {
m =(s+r) div 2;
if(x[m] < a)
s = m+1;
else
r = m;
}
for( j = i; j > r+1 ; j-- )
x[j] = x[j-1];
}
x[r] = a;
}
}
Universidad Técnica Federico Santa María - Departamento de Informática
Inserción binaria
• Similar a la inserción directa, realiza el mismo número de pasos,
toma la misma variable auxiliar ´a´ e inicializa 2 variables.
• El ordenamiento se lleva a cabo de la siguiente manera: Saca
mitad de s y r, compara el contenido de la mitad con el valor de
“a" si es más grande, hace más grande el límite superior de lo
contrario, hace más grande el límite inferior.
• Este proceso se realiza mientras el límite inferior sea menor que el
superior, después se realiza un ciclo decrementado donde los
números mayores se van bajando, y por ultimo se asignan el valor
de “a", al contenido del rango “r".
Universidad Técnica Federico Santa María - Departamento de Informática
Algoritmos de Inserción: Shell
• También llamado Ordenamiento de disminución incremental.
• Ordena subgrupos de elementos separados k unidades (respecto
de su posición en el arreglo) del arreglo original.
• El valor k es llamado incremento.
• Después de que los primeros k subgrupos han sido ordenados
(generalmente utilizando insercion directa), se escoge un nuevo
valor de k más pequeño, y el arreglo es de nuevo dividido entre el
nuevo conjunto de subgrupos.
• Cada uno de los subgrupos mayores es ordenado y el proceso se
repite de nuevo con un valor más pequeño de k.
• Eventualmente el valor de k llega a ser 1, de tal manera que el
subgrupo consiste de todo el arreglo ya casi ordenado.
• Al principio del proceso se escoge la secuencia de decrecimiento
de incrementos; el último valor debe ser 1.
Universidad Técnica Federico Santa María - Departamento de Informática
Algoritmos de Inserción: Shell
• Es como hacer un ordenamiento de burbuja pero comparando e
intercambiando elementos.
• Cuando el incremento toma un valor 1, todos los elementos pasan
a formar parte del subgrupo y se aplica inserción directa.
• El método se basa en tomar como salto N/2 (siendo N el número
de elementos) y luego se va reduciendo a la mitad en cada
repetición hasta que el salto o distancia vale 1.
• Su complejidad es difícil de calcular y depende mucho de la
secuencia de incrementos que utilice.
• En general este método es el escogido para muchas aplicaciones
reales por ser muy simple teniendo un tiempo de ejecución
aceptable incluso para grandes valores de n.
Universidad Técnica Federico Santa María - Departamento de Informática
Shell - implementación
void Shell( int n; int x[ ] ) {
int aux, salto = n/2, i, j, k;
while (salto > 0) {
for ( i = salto +1; i <= n; i++ ) {
j = i - salto;
while ( j > 0 ) {
n = j + salto;
if ( x[j] <= x[k] ) j = 0;
else {
aux = x[j];
x[j] = x[k];
x[k] = aux;
}
j = j - salto;
}
}
salto = salto /2;
}
}
Universidad Técnica Federico Santa María - Departamento de Informática
Mergesort - implementación
Shell - ejemplo
• Para el arreglo a = [ 6, 1, 5, 2, 3, 4, 0 ], se tiene el siguiente
recorrido:
Recorrido Salto Lista Ordenada
Intercambio
1
3
2, 1, 4, 0, 3, 5, 6 (6,2), (5,4), (6,0)
2
3
4
3
3
1
0, 1, 4, 2, 3, 5, 6
0, 1, 4, 2, 3, 5, 6
0, 1, 2, 3, 4, 5, 6
(2,0)
Ninguno
(4,2), (4,3)
5
1
0, 1, 2, 3, 4, 5, 6
Ninguno
Universidad Técnica Federico Santa María - Departamento de Informática
Algoritmos por distribución:
Método de conteo
void conteo(int n, int x[ ] ) {
int s[n], p, i, j;
for ( i = 1; i <= n; i++ ) {
p =1;
for( j = 1; j <= n; j++)
if (x[i] > x[j])
p++;
s[p]=x[i];
}
}
1 [20] [1]
2 [15] [8]
3 [8] [15]
4 [1]
[20]
i = 1, 2, 3, 4
p = 1, 2, 3, 4 |1,2,3,4| |1,2,3 | |1, 2
|
j = 1, 2, 3, 4 |1,2,3,4| |1,2,3,4| |1,2,3,4|
Universidad Técnica Federico Santa María - Departamento de Informática
|1
|
Universidad Técnica Federico Santa María - Departamento de Informática
Algoritmos de Intercalación: Mergesort
• Utiliza la técnica de Divide y Vencerás.
• Su estrategia consiste en dividir el vector en dos subvectores,
ordenarlos mediante llamadas recursivas, y finalmente combinar
los dos subvectores ya ordenados.
void Mezcla( vector a,b; int prim,ult ) {
// utiliza el vector b como auxiliar para realizar la mezcla
int mitad;
if ( prim < ult ) {
mitad = ( prim + ult ) / 2;
Mezcla ( a, b, prim, mitad );
Mezcla ( a, b, mitad+1, ult );
Combinar ( a, b, prim, mitad, mitad+1 ,ult );
}
}
Universidad Técnica Federico Santa María - Departamento de Informática
Mergesort - implementación
void Combinar(vector a, b; int p1,u1,p2,u2) {
// mezcla ordenadamente los subvectores a[p1..u1] y a[p2..u2] suponiendo que están ya
// ordenados y que son consecutivos (p2 = u1+1), utilizando el vector auxiliar b.
int i1, i2, k;
if ( ( p1 > u1) || ( p2 > u2 ) ) exit (1);
for ( k = p1; k <= u2; k++ ) {
b[k] = a[k];
} // volcamos a en b
i1 = p1;
i2 = p2; // cada indice se encarga de un subvector
for ( k = p1; k <= u2; k++ ) {
if ( b[i1] <= b[i2] ) {
else {
a[k] = b[i1];
a[k] = b[i2];
if ( i1 < u1 ) i1++;
if ( i2 < u2 ) i2++;
else b[i1] = max_int;
else b[i2] = max_int;
}
}
}
}
Universidad Técnica Federico Santa María - Departamento de Informática
Algoritmos por intercalación: merge
void Merge( int an,ab,cn ) {
int apa =1, apb =1, apc =1;
if ( ( an + bn ) > cn )
printf("ERROR");
else {
while( (apa <= an) && (apb <= bn) ) {
if a[apa] < b[apb]) {
c[apc] = a[apa];
apa++;
}
else {
c[apc] = b[apb];
apb++;
}
apc++;
}
while( apa <= an ) {
c[apc] = a[apa];
apa ++;
apc ++;
}
while (apb <= bn) {
c[apc] =b[apb];
apb++;
apc++;
}
}
}
Universidad Técnica Federico Santa María - Departamento de Informática
Universidad Técnica Federico Santa María - Departamento de Informática
Ordenación por Cubetas (Binsort)
Algoritmos de Intercalación: Mergesort
• Ordena n elementos en tiempo Θ(nlogn) en cualquiera de los
casos (peor, mejor o medio).
• Sin embargo tiene una complejidad espacial, en cuanto a
memoria, mayor que los demás (del orden de n).
• Otras versiones de este algoritmo no utilizan el vector auxiliar b,
sino que trabajan sobre el propio vector a ordenar, combinando
sobre él los subvectores obtenidos de las etapas anteriores.
• Consigue ahorrar espacio (un vector auxiliar), pero complica
el código del algoritmo resultante.
void Cubetas ( vector a ) {
int i;
for ( i = 1; i <= n; i++ ) {
while ( a[i] != i ) {
swap ( a, i, a[i] );
}
}
}
Universidad Técnica Federico Santa María - Departamento de Informática
Universidad Técnica Federico Santa María - Departamento de Informática
Ordenación por Residuos (Radix)
Algoritmos de Intercalación: Mergesort
• Se adapta muy bien a distintas circunstancias, por lo que es
comúnmente utilizado no sólo para la ordenación de vectores.
• Por ejemplo, el método puede ser también implementado de
forma que el acceso a los datos se realice de forma secuencial,
por lo que hay diversas estructuras (como las listas enlazadas)
para las que es especialmente apropiado.
• También se utiliza para realizar ordenación externa, en donde el
vector a ordenar reside en dispositivos externos de acceso
secuencial (i.e. archivos).
•
•
•
Universidad Técnica Federico Santa María - Departamento de Informática
Universidad Técnica Federico Santa María - Departamento de Informática
Ordenación por Residuos (Radix)
Ordenación por Cubetas (Binsort)
• Se supone que los datos a ordenar son números naturales, todos
distintos y comprendidos en el intervalo [1,n].
• Es decir, el problema es ordenar un vector con los n primeros
números naturales.
• Bajo esas circunstancias es posible implementar un algoritmo de
complejidad temporal O(n): ordenación por Cubetas,
• en cada iteración se sitúa un elemento en su posición
definitiva.
Puede utilizarse cuando los valores a ordenar están compuestos
por secuencias de letras o dígitos que admiten un orden
lexicográfico.
El método consiste en definir k colas (numeradas de 0 a k–1)
siendo k los posibles valores que puede tomar cada uno de los
dígitos que componen la secuencia.
Una vez tengamos las colas habría que repetir, para i a partir de 0
y hasta llegar al número máximo de dígitos o letras de nuestras
cadenas:
1. Distribuir los elementos en las colas en función del dígito i.
2. Extraer ordenada y consecutivamente los elementos de las
colas, introduciéndolos de nuevo en el vector.
•
•
•
•
Sea el vector: [0, 1, 81, 64, 23, 27, 4, 25, 36, 16, 9, 49].
En este caso se trata de números naturales en base 10, que son
secuencias de dígitos.
Se necesitan 10 colas.
• Cada uno de los dígitos puede tomar 10 valores (del 0 al 9)
En la primera pasada se introducen los elementos en las colas de
acuerdo a su dígito menos significativo:
Universidad Técnica Federico Santa María - Departamento de Informática
Universidad Técnica Federico Santa María - Departamento de Informática
Ordenación por Residuos (Radix)
•
Extraer ordenada y sucesivamente los valores, obteniendo el
vector: [0, 81, 1, 23, 4, 64, 25, 16, 36, 27, 49, 9].
Volver a realizar otra pasada, esta vez tomando el segundo dígito
menos significativo:
•
•
Búsqueda
Mauricio Solar
Lorna Figueroa
Volviendo a extraer ordenada y sucesivamente los valores se
obtiene el vector: [0, 1, 4, 9, 16, 23, 25, 27, 36, 49, 64, 81].
Como el máximo de dígitos de los números a ordenar era dos,
con dos pasadas es suficiente.
•
Universidad Técnica Federico Santa María - Departamento de Informática
Ordenación por Residuos (Radix)
typedef struct colaitem {
vector elems;
int cont
}
void Residuos(vector a; int B, prim, ult) {
int i, j, k, h, digito iter;
boolean sigo;
colaitem colas[MAXB-1];
iter = 1; // iter va acumulando B1,B2,B3,...
do
// para cada uno de los digitos
for ( i = 0; i <= B-1; i++ )
// inicializar las colas
colas[i].cont = 1;
// primera posicion libre
// clasificacion de los elementos en las colas
sigo = false;
// indica si quedan numeros con mas digitos
for ( i = prim; i <= ult; i++ ) {
sigo = ( ( a[i] / iter ) >= int( B ) ) || sigo;
Universidad Técnica Federico Santa María - Departamento de Informática
Ordenación por Residuos (Radix)
digito = ( a[i] / iter ) % int(B);
// num cola
colas[digito].elems[colas[digito].cont] = a[i];
colas[digito].cont++;
// inserta a[i] en su cola
}
}
iter = iter*int(B);
j = prim; // ahora volcamos las colas sobre el vector
for ( i = 0; i<= B-1; i++ ) {
h = colas[i].cont-1;
// num de elementos en esa cola
for ( k = 1; k <= h; k++ ) {
a[j] = colas[i].elems[k];
j++;
}
}
while ( ! Sigo );
2008
Universidad Técnica Federico Santa María - Departamento de Informática
Búsqueda
• La recuperación de información es una de las más importantes
aplicaciones de los computadores.
• Dado un nombre entregar un número telefónico asociado.
• Dado un número o nombre se deben encontrar los registros
personales de dicho nombre o clave.
• En estos ejemplos se está dando una parte de la información, la
llave (o clave) y se está preguntando para encontrar un registro
que contiene más información asociada con la llave.
• La búsqueda de llaves para encontrar registros es a veces la acción
que requiere más tiempo en un programa.
Universidad Técnica Federico Santa María - Departamento de Informática
Clasificación de Técnicas de Búsqueda
• Búsqueda interna.
• Los registros se mantienen dentro de la memoria del
computador.
• Búsqueda externa.
• Hay muchos registros y cada uno muy grande o extenso y es
necesario almacenarlos en archivos o en medios externos.
Universidad Técnica Federico Santa María - Departamento de Informática
Universidad Técnica Federico Santa María - Departamento de Informática
Clasificación de Técnicas de Búsqueda
• Búsqueda por comparación de llaves.
• Se tiene la búsqueda secuencial, que es una técnica de
búsqueda que mejora la eficiencia de un archivo ordenado
pero requiere mayor espacio.
• Búsqueda por transformación de llaves.
• El valor de la llave se transforma en un índice de una tabla
para obtener una dirección.
Universidad Técnica Federico Santa María - Departamento de Informática
Algoritmos de Búsqueda
• Búsqueda por comparación de llaves
• Secuencial
• Secuencial encadenada
• Secuencial indexada
• Secuencial binaria
• Árbol binario de búsqueda
• ….
• Búsqueda por transformación de llaves
• Funciones hash
• Método de la división
• Método del cuadrado
• Método de pliegue
• …..
Universidad Técnica Federico Santa María - Departamento de Informática
Búsqueda por comparación de llaves
Búsqueda por comparación de llaves
2. Búsqueda secuencial encadenada.
•
•
•
Almacena una tabla o archivo como lista encadenada.
Ventaja: el tamaño de la tabla puede ser aumentada
únicamente de acuerdo a los requerimientos.
Asume que la tabla está organizada como una lista
encadenada lineal.
Universidad Técnica Federico Santa María - Departamento de Informática
Búsqueda por comparación de llaves
2.- ALGORITMO DE BUSQUEDA BINARIA.
• Este método es el más eficiente en un tabla o archivo secuencial.
• El argumento de búsqueda es comparado con la llave del
elemento central de la tabla, si estos son iguales entonces termina
la búsqueda, si no, continua la búsqueda con la parte superior o
inferior de la tabla siguiendo los mismos pasos.
• Válido exclusivamente para vectores ordenados.
• Termina si se encuentra el valor buscado o si el tamaño del
intervalo de búsqueda queda anulado.
• En los casos en que existan repeticiones en el vector, del valor
buscado, obtendrá uno de ellos aleatoriamente según los lugares
que ocupen, los cuales necesariamente son consecutivos.
Universidad Técnica Federico Santa María - Departamento de Informática
Búsqueda por comparación de llaves
1. Búsqueda secuencial. int A_SECUENCIAL( int llave; int k [ ] ) {
int i = 1, n;
boolean f = false;
while( ( i<=n ) && ( ! ( f ) )
if ( llave == k[i] ) {
posic = i;
f = true;
}
else
i++;
if ( ! f )
posic = 0;
return posic;
}
#include <stdio.h>
void main (void)
{ int vector [100], x, enc, i, centro, izqda, dcha;
for (i = 0; i <= 99; i++)
// ingreso de datos al arreglo
vector[i] = i * 2;
x = i / 2;
// Escritura en pantalla del vector ordenado
printf ("\n\nVector:\n");
for (i = 0; i < 100; i++)
printf ("%d\t", vector[i]);
Universidad Técnica Federico Santa María - Departamento de Informática
Búsqueda por comparación de llaves
printf ("\nValor a buscar: %d", x);
// Búsqueda binaria en vector ordenado
enc = 0;
izqda = 0;
dcha = 99;
while (! enc && izqda <= dcha) {
centro = (izqda + dcha) / 2;
if (x < vector[centro])
dcha = centro - 1;
else if (x > vector[centro])
izqda = centro + 1;
else
enc = 1;
}
Universidad Técnica Federico Santa María - Departamento de Informática
Búsqueda por comparación de llaves
// Escritura en pantalla del vector ordenado
if (enc)
printf("\n%d encontrado en índice %d ", x, centro);
else
printf ("\n\nNo existe el valor %d en el vector.", x);
getch ();
}
Universidad Técnica Federico Santa María - Departamento de Informática
Búsqueda por comparación de llaves
// Implementación recursiva del algoritmo de Búsqueda Binaria
#define FALSE 0
#define TRUE 1
int búsqueda( int vec[ ], int elem, int limiteInf, int limiteSup ) {
int medio;
}
if ( limiteInf > limiteSup )
return FALSE;
else if(vec[ medio = (limiteInf + limiteSup +1 ) / 2 ] == elem )
return TRUE;
else if ( elem < vec[ medio ] )
return búsqueda( vec, elem, limiteInf, medio-1 );
else
return búsqueda( vec, elem, medio+1, limiteSup );
Universidad Técnica Federico Santa María - Departamento de Informática
Búsqueda por comparación de llaves
ALGORITMO FIBONACCI:
• Algoritmo de búsqueda es para un arreglo ordenado que utiliza la
secuencia numérica de Fibonacci como parte del proceso.
• Se utiliza un arreglo que contiene los números Fibonacci.
• La secuencia Fibonacci consiste en que cada elemento es la suma
de los dos elementos anteriores.
0, 1, 1, 2, 3, 5, 8, 13,.............
Universidad Técnica Federico Santa María - Departamento de Informática
int FIBONACCI( int llave,n, K[ ], FIB[ ] ) {
int T, J = 1, mitad = 1/n;
boolean fin;
while((FIB[J] != K[mitad] ) && ( ! fin) )
if ((mitad <= 0) || (llave> K[mitad]))
if ( F1 = = 1 )
fin = true
else {
mitad = mitad + F2;
F1 = F1 - F2;
F2 = F2 - F1;
}
else {
if (F2 == 0 ) fin = true;
else {
mitad = mitad - F2;
T = F1 - F2;
F2 = T;
}
if ( fin ) return 0;
else
return mitad;
}
Universidad Técnica Federico Santa María - Departamento de Informática
Referencias
• Apuntes y notas personales
• ¿Qué es ordenamiento?; Raiger Murillo Moreno.
• Aho, J.E. Hopcroft y J. D. Ullman, Data structures and
algorithms.
• T. Cormen, C. Leiserson y R. Rivest, Introduction to Algorithms.
• H. R. Lewis y L. Denenderg, Data Structures and Their
Algortihms.
• D. E. Knuth, The Art of Computer Programing, Vol. 1,
Fundamental Algorithm, y Vol. 3, Sorting and Searching.
• R. Sedgewick, Algorithms.
• G. H. Gonnet y R. Baeza-Yates, Handbook of Algorithms and
Data Structure.
Descargar