tres algoritmos de ordenación

Anuncio
TRES ALGORITMOS DE ORDENACIÓN
En el programa Ordenacion.exe, de demostración sobre algoritmos de ordenación, se pueden hacer
pruebas con los tres algoritmos distintos que a continuación describimos, el de La Burbuja, el de Inserción
Directa y el de Ordenación Shell con centinela.
El programa permite realizar la ordenación cronometrada, de forma ascendente o descendente, de una
lista aleatoria de 30.000 números y pudiendo utilizar cada vez cualquiera de estos tres algoritmos. Esto nos
permite establecer comparaciones de eficacia entre ellos aunque con ciertas limitaciones por el centinela de
lista ordenada del que carece el algoritmo de Inserción Directa y del que si disponen los otros dos, así como del
hecho de que el punto de partida más desfavorable es distinto en el caso de los algoritmos de La Burbuja y el
de Inserción Directa (La lista ordenada en sentido inverso, ascendente o descendente, al que se pretende
realizar cada vez y los podemos probar con este programa), mientras que para el algoritmo de Ordenación
Shell con centinela necesitaríamos crear un orden inverso a su peculiar forma de operar y para el que, tal y
como puede comprobarse haciendo pruebas con el programa, el caso más desfavorable que podemos
reproducir con este programa es el orden aleatorio que nos proporciona la generación de la lista.
I – ALGORITMO DE LA BURBUJA:
Recibe este nombre por que el movimiento de los elementos de la lista durante el proceso de
ordenación recuerda al de las burbujas en un líquido gasificado. En principio, se han de hacer tantas pasadas
como elementos tiene la lista menos uno y en cada pasada se van comparando, y haciendose los intercambios
pertinentes en su caso, los elementos por parejas, el primero con el segundo, el segundo con el tercero, etc.
De forma que en cada pasada al menos uno de los elementos queda colocado el la posición que le
corresponde (En la primera pasada el último, en la segunda el penúltimo, y así sucesivamente).
Este es el algoritmo menos eficiente en principio por que en todas las pasadas o vueltas ha de
comparar entre si a todos los elementos de la lista.
Sin embargo, este algoritmo lleva un centinela de ordenación que nos permite concluir el proceso
cuando en una pasada no ha sido necesario realizar ningún intercambio, por que este hecho acredita que la
lista ya está ordenada y por eso, en listas previamente ordenadas o semiordenadas es más eficiente que el de
inserción directa.
La codificación del algoritmo de La Burbuja en pseudocódigo es la siguiente:
INICIO
Ordenado:=FALSE
MIENTRAS NO ordenado
Ordenado:=TRUE
Para Iposicion desde INICIO hasta FINAL -1
SI Lista[IPosicion] > Lista[IPosicion+1]
Ordenado := FALSE
Comodin := Lista[IPosicion]
Lista[IPosicion] := Lista [IPosicion+1]
Lista[IPosicion+1] := Comodin
FIN SI
Siguiente IPosicion
FIN MIENTRAS
FIN
El diagrama de flujo de esta rutina es el siguiente:
INICIO
Ordenado=
FALSE
NO
Ordenado
FIN
Ordenado =
TRUE
Desde I = 1 hasta N - 1
Lista [I] >
Lista [I + 1]
Ordenado =
FALSE
Comodin =
Lista [I]
Lista [I] =
Lista [I + 1]
Lista [I + 1]
= Comodin
Siguiente I
II – ALGORITMO DE INSERCIÓN DIRECTA:
Este algoritmo trabaja de forma similar al de la burbuja, pero con diferencias que lo hacen algo más
eficiente. También en este caso se han de hacer tantas pasadas como elementos tiene la lista menos uno, pero
sólo en la primera pasada se comparan todos los elementos de la lista y se hacen los intercambios pertinentes.
La segunda pasada se inicia en el segundo elemento (En la primera pasada de las ordenaciones ascendentes
el elemento más pequeño de la lista ya ha quedado situado en primer lugar), la tercera en el tercer elemento y
así sucesivamente.
La diferencia con el algoritmo de La Burbuja estriba precisamente en el ahorro de comparaciones a
partir de la segunda pasada, pero como el tiempo empleado en hacer las comparaciones es mínimo y es el
intercambio de los datos el que consume la mayor parte del mismo, la diferencia entre estos dos algoritmos es
muy pequeña.
Por contra, el algoritmo de inserción directa no permite colocar un centinela de ordenación para
concluir el proceso cuando en una pasada no ha sido necesario realizar ningún intercambio, lo que lo hace
menos eficiente que el de La Burbuja para los casos se listas ordenadas o semiordenadas. Para explicar esto
supongamos que tenemos una lista formada por los número 1, 8, 5, 3, 7, 2, en la primera pasada no se
producirá ningún movimiento por que compara el primer elemento con todos los demás y es el mas pequeño
del grupo y eso no significa que la lista esté ordenada; mientras que con el algoritmo de La Burbuja en la
primera pasada se producirían 4 intercambios con el 8, primero con el 5, luego con el 3, después con el 7 y
finalmente con el 2, intercambios que con el algoritmo de Inserción Directa se producirían en la segunda vuelta.
La codificación del algoritmo de Inserción Directa en pseudocódigo es la siguiente:
INICIO
Para Iposicion desde INICIO hasta FINAL-1
Para Jposicion desde Iposicion+ 1 hasta FINAL
SI Lista[IPosicion] > Lista[JPosicion]
Comodin := Lista[IPosicion]
Lista[IPosicion] := Lista [JPosicion]
Lista[JPosicion] := Comodin
FIN SI
Siguiente JPosicion
Siguiente IPosicion
FIN
El diagrama de flujo del algoritmo de inserción directa es el siguiente:
INICIO
Desde I = 1 hasta N - 1
Desde J = I + 1 hasta N
Lista [I] >
Lista [J]
Comodin =
Lista [I]
Lista [I] =
Lista [J]
Lista [J] =
Comodin
Siguiente J
Siguiente I
FIN
III – ALGORITMO DE ORDENACIÓN SHELL CON CENTINELA:
Este algoritmo basa su eficiencia en los mismos principios de la búsqueda dicotómica sobre listas
ordenadas. Comienza dividiendo la lista en dos mitades y comparando (Y sustituyendo en su caso) el primero
con el que ocupa la posición de la mitad+1, el segundo con el que ocupa la posición de la mitad+2, etc. Y repite
esta pasada hasta que todos los elementos de las posiciones comparadas han quedado ordenados entre si.
Luego divide la lista en cuartos y repite la operación, comparando ahora los elementos del primer cuarto con
los del segundo, los del segundo con los del tercero y los del tercero con los del cuarto, y así sucesivamente
hasta que el puntero divisor alcanza el valor 1 y se hacen sucesivas pasadas comparando el primer elemento
con el segundo, el segundo con el tercero, etc. (En este punto pasa a funcionar como el algoritmo de la
burbuja).
Su gran eficiencia, comparada con los otros dos algoritmos vistos anteriormente, se debe al ahorro de
comparaciones y sobre todo de intercambios de datos (Que es lo que más tiempo consume) que se han de
realizar. Tanto el algoritmo de La Burbuja como el de Inserción Directa colocan cada elemento en su lugar
siguiendo un sistema de acercamiento progresivo, de forma que antes de alcanzar el lugar que les corresponde
han ocupado una serie de puestos intermedios llegando, en los casos más desfavorables (Cuando el elemento
más pequeño está situado en el último lugar de la lista o el más grande en el primero), a pasar por todas las
posiciones de la lista durante el proceso de ordenación. Por el contrario, con el algoritmo de ordenación Shell
los intercambios se realizan a saltos hasta el último paso en que, como hemos dicho, trabaja igual que el de la
burbuja, pero para entonces la mayor parte del trabajo ya está hecho. Así, si tenemos al elemento mayor en el
primer lugar de la lista, en el primer intercambio se situaría en la posición de la mitad+1, y con dos o tres
intercambios más alcanzaría su posición en el último lugar de la lista.
Además, este algoritmo, al igual que el de La Burbuja, tiene un centinela de ordenación para concluir
cada tipo de vuelta cuando no ha sido necesario realizar ningún intercambio, de forma que no tiene por que
agotar todas las comparaciones que serian necesarias sin él, lo que le añade un plus de efectividad. En este
caso consideramos un tipo de pasada o vuelta a cada división del puntero intermedio, que determina el
intervalo de la posición de los elementos que se comparan (La mitad, la cuarta parte, la octava parte ..., hasta
que adquiere el valor 1).
La codificación del algoritmo Shell con centinela en pseudocódigo es la siguiente:
INICIO
PunteroMedio := N
MIENTRAS PunteroMedio > 1
Ordenado := FALSE;
PunteroMedio := REDONDEO(PunteroMedio / 2)
MIENTRAS NO Ordenado
Ordenado := TRUE
PunteroInicial := 1
MIENTRAS PunteroInicial <= N - PunteroMedio
SI Lista[PunteroInicial] > Lista[PunteroInicial + PunteroMedio]
Ordenado := FALSE
Comodin := Lista[PunteroInicial + PunteroMedio]
Lista[PunteroInicial + PunteroMedio] := Lista [PunteroInicial]
Lista[PunteroInicial] := Comodin
FIN SI
PunteroInicial := PunteroInicial + 1
FIN MIENTRAS
FIN MIENTRAS
FIN MIENTRAS
FIN
El diagrama de flujo del algoritmo de ordenación Shell con centinela es el siguiente:
INICIO
PunteroMedio = N
PunteroMedio
>1
Ordenado = FALSE;
PunteroMedio = REDONDEO
(PunteroMedio / 2);
FIN
Ordenado
Ordenado = TRUE;
PunteroInicial = 1;
PunteroInicial <= N
- PunteroMedio
Lista[PunteroInicial] >
Lista [PunteroInicial +
PunteroMedio]
Ordenado = FALSE;
Comodin = Lista [PunteroInicial +
PunteroMedio];
Lista [PunteroInicial +
PunteroMedio] = Lista
[PunteroInicial];
Lista [PunteroInicial] = Comodin;
PunteroInicial = PunteroInicial
+ 1;
Serafín Medina Montañés
Descargar