Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Algoritmo de la burbuja
En el caso de un array (lista) con n elementos, la ordenación por burbuja requiere hasta
n-1 pasadas. Por cada pasada se comparan elementos adyacentes y se intercambian sus
valores cuando el primer elemento es mayor que el segundo elemento. Al final de cada
pasada, el elemento mayor ha “burbujeado” hasta la cima de la sublista actual. Por
ejemplo, después que la pasada 0 está completa, la cola de la lista a[n-1] está ordenada
y el frente de la lista permanece desordenado. Las etapas del algoritmo son :
Pasada 1 50 20 40 80 30 Intercambio 50 y 20
20 50 40 80 30 Intercambio 50 y 40
20 40 50 80 30 50 y 80 ordenados
20 40 50 80 30 Intercambio 80 y 30
• Elemento mayor es 80
20 40 50 30 80 • interruptor = TRUE
Pasada 2
20 40 50 30 80 20 y 40 ordenados
20 40 50 30 80 40 y 50 ordenados
20 40 50 30 80 Se intercambian 50 y 30
Pasada 3
20 40 30 50 80 20 y 40 ordenados
• Se intercambian 40 y 30
20 30 40 50 80 • interruptor = TRUE
Pasada 4
20 30 40 50 80 20 y 30 ordenados
• Lista ordenada
20 30 40 50 80 • interruptor = FALSE
Una mejora del algoritmo anterior consiste en utilizar, en lugar de una variable
bandera interruptor, una variable indiceIntercambio que se inicie a 0 al principio
de cada pasada y se establezca al índice del último intercambio, de modo que cuando al
terminar la pasada el valor de indiceIntercambio siga siendo 0 implicará que no se ha
producido ningún intercambio (o bien, que el intercambio ha sido con el primer
elemento) , y, por consiguiente, la lista estará ordenada. En caso de no ser 0, el valor de
indiceIntercambio representa el índice del array a partir del cual los elementos están
ordenados. La codificación de esta alternativa:
public static void ordBurbuja2 (long a[])
{
int i, j;
int indiceIntercambio;
int n = a.length;
i = n-1;
while (i > 0)
{
indiceIntercambio = 0;
// explorar la sublista a[0] a a[i]
for (j = 0; j < i; j++)
if (a[j+1] < a[j])
{
indiceIntercambio = j;
intercambiar(a, j, j+1);
}
i = indiceIntercambio;
}
}
Análisis del algoritmo de la burbuja
A tener en cuenta
Los algoritmos de ordenación interna: intercambio, selección, inserción y burbuja son
fáciles de entender y de codificar, sin embargo poco eficientes y no recomendables para
ordenar listas de muchos elementos. La complejidad de todos ellos es cuadrática, 0(n2).
EJERCICIO 1
import ordenainterna.MetodosBasicosOrdenacion;
import java.io.*;
entrada(v);
System.arraycopy(v,0,c,0,v.length);
k1 = System.currentTimeMillis();
OrdenacBasica.ordIntercambio(c);
k2 = System.currentTimeMillis();
System.out.println("\nTiempo ordenación por intercambio: "
+ (k2 - k1));
System.arraycopy(v,0,c,0,v.length);
k1 = System.currentTimeMillis();
OrdenacBasica.ordInsercion(c);
k2 = System.currentTimeMillis();
System.out.println("\nTiempo ordenación por inserción: "
+ (k2 - k1));
System.arraycopy(v,0,c,0,v.length);
k1 = System.currentTimeMillis();
OrdenacBasica.ordBurbuja(c);
k2 = System.currentTimeMillis();
System.out.println("\nTiempo ordenación por burbuja: "
+ (k2 - k1));
System.arraycopy(v,0,c,0,v.length);
k1 = System.currentTimeMillis();
OrdenacBasica.ordBurbuja2(c);
k2 = System.currentTimeMillis();
System.out.println("\nTiempo ordenación por burbuja(2): "
+ (k2 - k1));
System.arraycopy(v,0,c,0,v.length);
k1 = System.currentTimeMillis();
OrdenacBasica.ordSeleccion(c);
k2 = System.currentTimeMillis();
System.out.println("\nTiempo ordenación por seleccion: "
+ (k2 - k1));
}
static void entrada(int [] w)
{
int SUP =9999;
for (int i = 0; i< w.length; i++)
w[i] = (int)(Math.random() * SUP + 1);
}
}
MÉTODOS DE ORDENACIÓN BINSORT Y RADIXSORT
Estos métodos de ordenación utilizan urnas para depositar en ellas los registros en el
proceso de ordenación. En cada recorrido de la lista a ordenar se deposita en una urnai
aquellos registros cuya clave tienen una cierta correspondencia con el índice i .
Este método, también llamado clasificación por urnas, se propone conseguir funciones
tiempo de ejecución de complejidad menor de O(n log n) para ordenar una lista de n
elementos, siempre que se conozca alguna relación del campo clave de los elementos
respecto de las urnas.
Dado un array v[]de registros, se desea ordenar respecto un campo clave de tipo
entero, además se sabe que los valores de las claves se encuentran en el rango de 1 a n,
sin claves duplicadas y siendo n el número de elementos. En estas circunstancias
ideales es posible ubicar los registros ordenados en un array auxiliar t[] mediante este
único bucle:
for i = 1 to n do
t[v[i].clave]= v[i];
Urnas
1 R1 R1 R1
2 R2 R2 R2
R3 R3 R3
m Rm Rm Rm
El algoritmo se aplica sobre listas de registros con un campo clave cuyo rango de
valores es relativamente pequeño respecto al número de registros. Normalmente el
campo clave es de tipo entero, en el rango 1 .. m. Son necesarias m urnas por ello se
declara un vector de m urnas. Las urnas se representan mediante listas enlazadas, cada
elemento de la lista contiene un registro cuyo campo clave se corresponde con el índice
de la urna en la que se encuentra, normalmente la clave será igual al índice de la urna.
Así en la urna 1 se sitúan los registros cuyo campo clave es 1, en la urna 2 los registros
cuyo campo clave es 2, y así sucesivamente en la urna i se sitúan los registros cuyo
campo clave es igual a i .
La primera acción del algoritmo consiste en distribuir los registros en las diversas
urnas. Una vez realizada la distribución, es necesario concatenar las listas enlazadas
para formar un única lista con los registros en orden creciente; por último, se recorre la
lista asignando cada nodo al vector, y de esa manera el vector de registros queda en
orden respecto al campo clave. La Figura 6.4 se muestra cómo realizar la
concatenación.
R1 R1 R1
R2 R2 R2
R3 R3 ... R3
Rm Rm Rm
345, 721, 425, 572, 836, 467, 672, 194, 365, 236, 891, 746, 431,
721, 891, 431, 572, 672, 194, 834, 345, 425, 365, 836, 236, 746, 216,
467, 247, 529, 389
Esta lista ya está ordenada respecto al dígito de menor peso, respecto a las unidades.
Pues bien, ahora de nuevo se distribuye la secuencia de fichas en montones respecto al
segundo dígito:
236
529 836 247
425 834 746 467 672 194
216 721 431 345 365 572 389 891
1 2 3 4 6 7 8 9
En este momento las fichas ya están ordenadas respecto a los dos últimos dígitos, es
decir respecto a las decenas. Por último, se distribuye las fichas en montones respecto
al tercer dígito:
OrdenacionRadixsort(vector, n)
inicio
{ cálculo el número máximo de dígitos: ndig }
ndig = 0;
temp = maximaClave;
mientras (temp > 0) hacer
ndig = ndig+1
temp = temp / 10;
fin_mientras
peso =1 { permite obtener los dígitos de menor a mayor peso}
desde i = 1 hasta ndig hacer
CrearUrnas(Urnas);
desde j = 1 hasta n hacer
d = (vector[j] / peso) modulo 10;
AñadirEnUma(Urnas[d], vector[j]);
fin_desde
{ búsqueda de primera urna no vacía: j }
desde r = j+1 hasta M hace { M: número de urnas }
EnlazarUma(Urnas[r], Urnas[j]);
fin_desde
{Se recorre la lísta-urna resultante de la concatenación}
r = 1;
dir = frente(Urna[j]);
mientras dir <> nulo hacer
vecto[r] = dir.registro;
r = r+1;
dir = siguiente(dir)
fin_mientras
peso = peso * 10;
fin_desde
fin_ordenacion
Métodos de ordenación básicos
package ordenainterna;
i = n-1;
while (i > 0)
{
indiceIntercambio = 0;
// explorar la sublista a[0] a a[i]
for (j = 0; j < i; j++)
if (a[j+1] < a[j])
{
indiceIntercambio = j;
intercambiar(a, j, j+1);
}
i = indiceIntercambio;
}
}
n = a.length;
// ordenar a[0]..a[n-2] y a[n-1] en cada pasada
for (i = 0; i < n-1; i++)
{
// comienzo de la exploración en índice i
indiceMenor = i;
// j explora la sublista a[i+1]..a[n-1]
for (j = i+1; j < n; j++)
if (a[j] < a[indiceMenor])
indiceMenor = j;
// sitúa el elemento mas pequeño en a[i]
if (i != indiceMenor)
intercambiar(a, i, indiceMenor);
}
}
}
Métodos de ordenación Shell
public static void ordenacionShell(double a[])
{
int intervalo, i, j, k;
int n= a.length;
intervalo = n / 2;
while (intervalo > 0)
{
for (i = intervalo; i < n; i++)
{
j = i - intervalo;
while (j >= 0)
{
k = j + intervalo;
if (a[j] <= a[k])
j = -1; // par de elementos ordenado
else
{
intercambiar(a, j, j+1);
j -= intervalo;
}
}
}
intervalo = intervalo / 2;
}
}
Método de ordenación quicksort
public static void quicksort(double a[])
{
quicksort(a, 0, a.length-1);
}
int i, j, central;
double pivote;
do {
while (a[i] < pivote) i++;
while (a[j] > pivote) j--;
if (i <= j)
{
intercambiar(a, i, j);
i++;
j--;
}
}while (i <= j);
if (primero < j)
quicksort(a, primero, j); // mismo proceso con sublista izqda
if (i < ultimo)
quicksort(a, i, ultimo); // mismo proceso con sublista drcha
}
}
private static void intercambiar (Vector v, int i, int j)
{
Object aux = v.elementAt(i);
v.setElementAt(v.elementAt(j), i);
v.setElementAt(aux, j);
}
public static void ordVector (Vector v)
{
boolean interruptor = true;
int pasada, j;
int n = v.size();
// bucle externo controla la cantidad de pasadas
for (pasada = 0; pasada < n-1 && interruptor; pasada++)
{
interruptor = false;
for (j = 0; j < n-pasada-1; j++)
{
Racional r;
r = (Racional)v.elementAt(j);
if (r.mayorQue(v.elementAt(j+1)))
{
// elementos desordenados, se intercambian
interruptor = true;
intercambiar(v, j, j+1);
}
}
}
}
Búsqueda binaria
bajo = 0;
alto = a.length - 1;
while (bajo <= alto)
{
central = (bajo + alto)/2; // índice de elemento central
valorCentral = a[central]; // valor del índice central
if (clave == valorCentral)
return central; // encontrado, devuelve posición
else if (clave < valorCentral)
alto = central -1; // ir a sublista inferior
else
bajo = central + 1; // ir a sublista superior
}
return -1; //elemento no encontrado
}