El ordenamiento de burbuja bidireccional
El ordenamiento de burbuja bidireccional (también llamado "método de la sacudida" o "coctail sort" o "shaker sort") es un algoritmo de ordenamiento que surge como una mejora del algoritmo ordenamiento de burbuja .
Si ya habéis visto como funciona el algoritmo de ordenación por burbuja habréis observado que los números grandes se están moviendo rápidamente hasta al final de la lista (estas son las "liebres"),
pero que los números pequeños (las "tortugas") se mueven sólo muy lentamente al inicio de la lista.
Una solución es de ordenar con el método de burbuja y cuando llegamos al final de la primera iteración, no volver a realizar el cálculo desde el principio sino que empezaremos desde el final
hasta al inicio. De esta manera siempre se consigue que tanto los números pequeños como los números grandes se desplacen a los extremos de la lista lo más rápido posible.
Representación animada del algoritmo :
Representación animada del ordenamiento de burbuja bidireccional
PROCEDIMIENTO cocktail_sort ( VECTOR a[ 1 : n] )
dirección ← 'frontal', comienzo ← 1, fin ← n-1, actual ← 1
REPETIR
permut ← FALSO
REPETIR
SI a[actual] > a[actual + 1] ENTONCES
intercambiar a[actual] Y a[actual + 1]
permut ← VERDADERO
FIN SI
SI (dirección='frontal') ENTONCES
actual ← actual + 1
SI NO
actual ←actual - 1
FIN SI
MIENTRAS QUE ( (dirección='frontal') Y (actual<fin)) OU ( (dirección= 'final) O (actual>comienzo))
SI (dirección='frontal') ENTONCES
dirección ← 'final'
fin ← fin - 1
SI NO
dirección ← 'frontal'
comienzo ← comienzo + 1
FIN SI
MIENTRAS permut = VERDADERO
FIN PROCEDIMIENTO
let cocktail_sort vector =
let permutation = ref true and actual = ref 0 and dirección = ref 1
and comienzo
= ref 0 and fin
= ref ( ( Array . length vector
) - 2 ) in
while ( ! permutation = true ) do
permutation := false ;
while ( ( ! dirección= 1 ) && ( ! actual < ! fin) ) || ( ( ! dirección = - 1 ) && ( ! actual > ! comienzo) ) do
actual := ! actual + ! dirección;
if vector. ( ! actual) > vector. ( ! actual + 1 ) then
begin
(* Intercambiamos los dos elementos *)
permutation := true ;
let temp = vector. ( ! actual) in
begin
vector. ( ! actual) <- vector. ( ! actual + 1 ) ;
vector. ( ! actual + 1 ) <- temp;
end
end
done ;
if ( ! dirección = 1 ) then fin := ! fin - 1 else comienzo := ! comienzo + 1 ;
dirección := - ! dirección;
done ;
vector;;
type tab = array [ 1 ..20 ] of integer ;
procedure cocktail_sort( var vector : tab) ;
var permutation : boolean ;
actual, temp : integer ;
dirección : integer ;
comienzo, fin : integer ;
begin
actual:= 1 ;dirección:= 1 ;
comienzo:= 0 ;fin:= 20 ;
REPEAT
permutation := false ;
while ( ( actual<fin) and ( dirección= 1 ) ) or
( ( dirección=- 1 ) and ( actual>comienzo) ) do
begin
actual:= actual+ dirección;
if vector[ actual] <vector[ actual- 1 ] then
begin
temp:= vector[ actual] ;
vector[ actual] := vector[ actual - 1 ] ;
vector[ actual - 1 ] := temp;
permutation:= true ;
end ;
end ;
if dirección= 1 then fin:= fin - 1 else comienzo:= comienzo + 1 ;
dirección:=- dirección;
UNTIL ( not permutation) ;
end ;
def cocktail_sort( vector) :
permutation,dirección,actual = True ,1 ,0
comienzo,fin = 0 ,len ( vector) -2
while permutation == True :
permutation = False
while ( actual< fin and dirección==1 ) or \
( actual> comienzo and dirección==-1 ) :
# Prueba si intercambio
if vector[ actual] > vector[ actual + 1 ] :
permutation = True
# Intercambiamos los dos elementos
vector[ actual] , vector[ actual + 1 ] = \
vector[ actual + 1 ] ,vector[ actual]
actual = actual + dirección
# Cambiar la dirección de desplazamiento
if dirección==1 :
fin = fin - 1
else :
comienzo = comienzo + 1
dirección = -dirección
return vector
typedef int bool;
enum { false , true } ;
void cocktail_sort( int * vector) {
bool permutation;
int actual= 0 , dirección= 1 ;
int comienzo= 1 , fin= 19 ;
do {
permutation= false ;
while ( ( ( dirección== 1 ) && ( actual< fin) ) || ( ( dirección==- 1 ) && ( actual> comienzo) ) ) {
actual += dirección;
if ( vector[ actual] < vector[ actual- 1 ] ) {
int temp = vector[ actual] ;
vector[ actual] = vector[ actual- 1 ] ;
vector[ actual- 1 ] = temp;
permutation= true ;
}
}
if ( dirección== 1 ) fin--; else comienzo++;
dirección = - dirección;
} while ( permutation) ;
}
Use este algoritmo para resolver el pequeño conjunto de la página anterior :
Comparaciones :
Movimientos :
Mezclar
Resolver
Los siguientes gráficos muestran el aumento en el número de transacciones en relación con el número de elementos a ser ordenados.
Rendimiento del algoritmo
En el caso óptimo, con los datos ya ordenados, el algoritmo sólo effectura n comparaciones. Por lo tanto la complejidad en el caso óptimo es en Θ(n ).
Rendimiento en el caso óptimo
Número de operaciones
Número de términos
Θ(n)
En el caso desfavorable, con los datos ordenados a la inversa, la complejidad es en Θ(n 2 ).
Rendimiento en el caso desfavorable
Número de operaciones
Número de términos
Θ(n2)
En el caso medio, la complejidad de este algoritmo es también en Θ(n 2 )
Rendimiento en el caso medio
NNúmero de operaciones
Número de términos
Θ(n2)