robot de la enciclopedia para niños

Ordenamiento de burbuja para niños

Enciclopedia para niños
Archivo:Bubble-sort-example-300px
Representación animada de ordenación de un conjunto de números mediante el algoritmo burbuja. Comenzando desde el inicio del arreglo, se compara cada par de elementos adyacentes. Si ambos no están ordenados (el segundo es menor que el primero), se intercambian sus posiciones. En cada iteración, un elemento menos necesita ser evaluados (el último), ya que no hay más elementos a su derecha que necesiten ser comparados, puesto que ya están ordenados.

El ordenamiento de burbuja (Bubble Sort en inglés) es un sencillo algoritmo de ordenamiento. Funciona revisando cada elemento de la lista que va a ser ordenada con el siguiente, intercambiándolos de posición si están en el orden equivocado. Es necesario revisar varias veces toda la lista hasta que no se necesiten más intercambios, lo cual significa que la lista está ordenada. Este algoritmo obtiene su nombre de la forma con la que suben por la lista los elementos durante los intercambios, como si fueran pequeñas "burbujas". También es conocido como el método del intercambio directo. Dado que solo usa comparaciones para operar elementos, se lo considera un algoritmo de comparación, siendo uno de los más sencillos de implementar.

Descripción

Una manera simple de expresar el ordenamiento de burbuja en pseudocódigo es la siguiente:


   { \color{Sepia} \mathit{ procedimiento }} \;
   { \color{red}  \mathit{ DeLaBurbuja }} \; 
   (
      { \color{Black}  \mathit{ a }}
      { \color{Plum}   \mathit{ {}_0 }} ,
      { \color{Black}  \mathit{ a }}
      { \color{Plum}   \mathit{ {}_1 }} ,
      { \color{Black}  \mathit{ a }}
      { \color{Plum}   \mathit{ {}_2 }} ,
      \ldots,
      { \color{Black}  \mathit{ a }} {}_(
      { \color{black}  \mathit{ {}_n }}
      { \color{Blue}   \mathit{ {}_- }}
      { \color{Plum}   \mathit{ {}_1}} {}_)
   )

   { \color{Sepia} \mathit{ para }} \;
   { \color{Black} \mathit{ i}} \;
   { \color{Blue}  \mathit{ \gets }} \;
   { \color{Plum}  \mathit{ 0}} \;
   { \color{Sepia} \mathit{ hasta }} \;
   { \color{Black} \mathit{ n}} \;
   { \color{Blue}  \mathit{ - }} \;
   { \color{Plum}  \mathit{ 2 }} \;
   { \color{Sepia} \mathit{ hacer }}

   { \color{Sepia} \mathit{ para }} \;
   { \color{Black} \mathit{ j}} \;
   { \color{Blue}  \mathit{ \gets }} \;
   { \color{Plum} \mathit{ 0}} \;
   { \color{Sepia} \mathit{ hasta }} \;
   { \color{Black} \mathit{ n }} \;
   { \color{Blue}  \mathit{ - }} \;
   { \color{Black} \mathit{ i }} \;
   { \color{Blue}  \mathit{ - }} \;
   { \color{Plum}  \mathit{ 2 }} \;
   { \color{Sepia} \mathit{ hacer }}

   { \color{Sepia} \mathit{ si }} \;
   { \color{Black} \mathit{ a }}    {}_(
   { \color{Black} \mathit{ {}_j }} {}_) \;
   { \color{Blue}  \mathit{ > }} \;
   { \color{Black} \mathit{ a }} {}_(
   { \color{Black} \mathit{ {}_j }}
   { \color{Blue}  \mathit{ {}_+ }}
   { \color{Plum}  \mathit{ {}_1}} {}_) \;
   { \color{Sepia} \mathit{ entonces }}

   { \color{Black} \mathit{ aux }} \;
   { \color{Blue}  \mathit{ \gets }} \;
   { \color{Black} \mathit{ a }}    {}_(
   { \color{Black} \mathit{ {}_j }} {}_) \;

   { \color{Black} \mathit{ a }}    {}_(
   { \color{Black} \mathit{ {}_j }} {}_) \;
   { \color{Blue}  \mathit{ \gets }} \;
   { \color{Black} \mathit{ a }} {}_(
   { \color{Black} \mathit{ {}_j }}
   { \color{Blue}  \mathit{ {}_+ }}
   { \color{Plum}  \mathit{ {}_1}} {}_)

   { \color{Black} \mathit{ a }} {}_(
   { \color{Black} \mathit{ {}_j }}
   { \color{Blue}  \mathit{ {}_+ }}
   { \color{Plum}  \mathit{ {}_1}} {}_) \;
   { \color{Blue}  \mathit{ \gets }} \;
   { \color{Black} \mathit{ aux }}

   { \color{Sepia} \mathit{ fin \; si }}

   { \color{Sepia} \mathit{ fin \; para }}

   { \color{Sepia} \mathit{ fin \; para }}

   { \color{Sepia} \mathit{ fin \; procedimiento }}

Este algoritmo realiza el ordenamiento o reordenamiento de una lista a de n valores, en este caso de n términos numerados del 0 al n-1; consta de dos bucles anidados, uno con el índice i, que da un tamaño menor al recorrido de la burbuja en sentido inverso de 2 a n, y un segundo bucle con el índice j, con un recorrido desde 0 hasta n-i, para cada iteración del primer bucle, que indica el lugar de la burbuja.

La burbuja son dos términos de la lista seguidos, j y j+1, que se comparan: si el primero es mayor que el segundo sus valores se intercambian.

Esta comparación se repite en el centro de los dos bucles, dando lugar a una lista ordenada. Puede verse que el número de repeticiones solo depende de n y no del orden de los términos, esto es, si pasamos al algoritmo una lista ya ordenada, realizará todas las comparaciones exactamente igual que para una lista no ordenada. Esta es una característica de este algoritmo. Luego veremos una variante que evita este inconveniente.

Para comprender el funcionamiento, veamos un ejemplo sencillo:

Tenemos una lista de números que hay que ordenar:


   a = \{55, 86, 48, 16, 82 \}  \,

  \begin{array}{r}
      a_{4} = 82 \\
      a_{3} = 16 \\
      a_{2} = 48 \\
      a_{1} = 86 \\
      a_{0} = 55 
   \end{array}

Podemos ver que la lista que tiene cinco términos, luego:


   n = 5 \,

El índice i hará un recorrido de 2 hasta n:


   { \color{Sepia} \mathit{ para }} \;
   { \color{Black} \mathit{ i}} \;
   { \color{BlueViolet} \mathit{ \gets }} \;
   { \color{Black} \mathit{ 2}} \;
   { \color{Sepia} \mathit{ hasta }} \;
   { \color{Black} \mathit{ n}} \;
   { \color{Sepia} \mathit{ hacer }}

que en este caso será de 2 a 5. Para cada uno de los valores de i, j tomará sucesivamente los valores de 0 hasta n-i:


   { \color{Sepia} \mathit{ para }} \;
   { \color{Black} \mathit{ j}} \;
   { \color{BlueViolet} \mathit{ \gets }} \;
   { \color{Black} \mathit{ 0}} \;
   { \color{Sepia} \mathit{ hasta }} \;
   { \color{Black} \mathit{ n-i}} \;
   { \color{Sepia} \mathit{ hacer }}

Para cada valor de j, obtenido en ese orden, se compara el valor del índice j con el siguiente:


   { \color{Sepia}      \mathit{ si }} \;
   { \color{Black} a_{(j)} } \;
   { \color{BlueViolet} > } \;
   { \color{Black} a_{(j+1)}} \;
   { \color{Sepia}      \mathit{ entonces }}

Si el término j es mayor que el término j+1, los valores se permutan, en caso contrario se continúa con la iteración.


  \begin{array}{r||r|r|r|r|r}
            & j =  0 & j =  1 & j =  2 & j =  3 &    \\
      \hline
      a_{4} &     82 &     82 &     82 & \to 82 & 86 \\
      a_{3} &     16 &     16 & \to 16 & \to 86 & 82 \\
      a_{2} &     48 & \to 48 & \to 86 &     16 & 16 \\
      a_{1} & \to 86 & \to 86 &     48 &     48 & 48 \\
      a_{0} & \to 55 &     55 &     55 &     55 & 55
   \end{array}

Para el caso del ejemplo, tenemos que:


   n = 5 \,

Para la primera iteración del primer bucle:


   i = 2 \,

y j tomará los valores de 0 hasta 3:


   { \color{Sepia} \mathit{ para }} \;
   { \color{Black} \mathit{ j}} \;
   { \color{BlueViolet} \mathit{ \gets }} \;
   { \color{Black} \mathit{ 0}} \;
   { \color{Sepia} \mathit{ hasta }} \;
   { \color{Black} \mathit{ 3}} \;
   { \color{Sepia} \mathit{ hacer }}

Cuando j vale 0, se comparan  a_0 \; a_1 , el 55 y el 86, dado que 55 < 86, no se permuta el orden.

Ahora j vale 1 y se comparan  a_1 \; a_2 el 86 y el 48. Como 86 > 48, se permutan, dando lugar a una nueva lista.

Se repite el proceso hasta que j valga 3, dando lugar a una lista parcialmente ordenada. Podemos ver que el término de mayor valor está en el lugar más alto.


  \begin{array}{r||r|r|r|r}
            & j =  0 & j =  1 & j =  2 &    \\
      \hline
      a_{4} &     86 &     86 &     86 & 86 \\
      a_{3} &     82 &     82 & \to 82 & 82 \\
      a_{2} &     16 & \to 16 & \to 55 & 55 \\
      a_{1} & \to 48 & \to 55 &     16 & 16 \\
      a_{0} & \to 55 &     48 &     48 & 48
   \end{array}

Ahora i vale 3, y j hará un recorrido de 0 a 2.

Primero j vale 0, se comparan  a_0 \; a_1 , el 55 y el 48. Como 55 > 48 se permutan dando lugar a la nueva lista.

Para j = 1 se compara el 55 con el 16 y se cambian de orden.

Para j = 2 se compara el 55 y el 82 y se dejan como están, finalizando el bucle con una lista mejor ordenada. Puede verse que los dos valores más altos ya ocupan su lugar. No se ha realizado ninguna comparación con el término cuarto, dado que ya se sabe que después del primer ciclo es el mayor de la lista.

El algoritmo consiste en comparaciones sucesivas de dos términos consecutivos ascendiendo de abajo arriba en cada iteración, como la ascensión de las burbujas de aire en el agua, de ahí el nombre del procedimiento. En la primera iteración el recorrido ha sido completo, en el segundo se ha dejado él último término, al tener ya el mayor de los valores, en los sucesivos sé ira dejando de realizar las últimas comparaciones, como se puede ver.


  \begin{array}{r||r|r|r}
            & j =  0 & j =  1 &    \\
      \hline
      a_{4} &     86 &     86 & 86 \\
      a_{3} &     82 &     82 & 82 \\
      a_{2} &     55 & \to 55 & 55 \\
      a_{1} & \to 16 & \to 48 & 48 \\
      a_{0} & \to 48 &     16 & 16
   \end{array}

Ahora ya i vale 4 y j recorrerá los valores de 0 a 1.

Cuando j vale 0, se comparan  a_0 \; a_1 , esto es, el 48 y el 16. Dado que 48 es mayor que 16 se permutan los valores, dando lugar a una lista algo más ordenada que la anterior. Desde esta nueva ordenación, j pasa a valer 1, con lo que se comparan los términos  a_1 \; a_2 el 48 y el 55 que quedan en el mismo orden.

En este caso la burbuja ha ascendido menos que en los casos anteriores, y la lista está ya ordenada, pero el algoritmo tendrá que completarse, realizando una última iteración.

Hay que tener en cuenta que el bucle realiza un número fijo de repeticiones y para finalizar tendrán que completarse, aun en el caso extremo, de que la lista estuviera previamente ordenada.

Por último i vale 5 y j solo puede vale 0, con lo que sólo se realizará una comparación de  a_0 \; a_1 el 16 y el 48, que ya están ordenados y se dejan igual.


  \begin{array}{r||r|r}
            & j =  0 &     \\
      \hline
      a_{4} &     86 & 86 \\
      a_{3} &     82 & 82 \\
      a_{2} &     55 & 55 \\
      a_{1} & \to 48 & 48 \\
      a_{0} & \to 16 & 16
   \end{array}

Los bucles finalizan y también el procedimiento, dejando la lista ordenada.

Una variante que finaliza en caso de que la lista esté ordenada, puede ser la siguiente: como en el ejemplo anterior, empleando un centinela ordenado, que detecta que no se ha modificado la lista en un recorrido de la burbuja, y que por tanto la lista ya está ordenada, finalizando inmediatamente.


      { \color{Sepia} procedimiento } \;
      { \color{BlueViolet} DeLaBurbuja2 } \; (
      { \color{Black} a_{(0)}, a_{(1)}, a_{(2)}, \ldots, a_{(n-1)}} )

   { \color{Black} i } \;
   { \color{BlueViolet} \gets } \;
   { \color{Black} 1} \;

   { \color{Black} ordenado } \;
   { \color{BlueViolet} \gets } \;
   { \color{Black} no} \;

   { \color{Sepia} \mathit{ mientras }} \;
   { \color{Black} \mathit{ (i < n) \; \land \; (ordenado = no)}} \;
   { \color{Sepia} \mathit{ hacer }}

   { \color{Black} i } \;
   { \color{BlueViolet} \gets } \;
   { \color{Black} i + 1} \;

   { \color{Black} ordenado } \;
   { \color{BlueViolet} \gets } \;
   { \color{Black} si} \;

   { \color{Sepia} \mathit{ para }} \;
   { \color{Black} \mathit{ j}} \;
   { \color{BlueViolet} \mathit{ \gets }} \;
   { \color{Black} \mathit{ 0}} \;
   { \color{Sepia} \mathit{ hasta }} \;
   { \color{Black} \mathit{ n-i}} \;
   { \color{Sepia} \mathit{ hacer }}

   { \color{Sepia}      \mathit{ si }} \;
   { \color{Black} a_{(j)} } \;
   { \color{BlueViolet} > } \;
   { \color{Black} a_{(j+1)}} \;
   { \color{Sepia}      \mathit{ entonces }}

   { \color{Black} ordenado } \;
   { \color{BlueViolet} \gets } \;
   { \color{Black} no} \;

   { \color{Black} aux } \;
   { \color{BlueViolet} \gets } \;
   { \color{Black} a_{(j)} } \;

   { \color{Black} a_{(j)} } \;
   { \color{BlueViolet} \gets } \;
   { \color{Black} a_{(j+1)}} \;

   { \color{Black} a_{(j+1)} } \;
   { \color{BlueViolet} \gets } \;
   { \color{Black} aux } \;

   { \color{Sepia}       \mathit{ fin \; si }}

   { \color{Sepia} \mathit{ fin \; para }}

   { \color{Sepia} \mathit{ fin \; mientras }}

   { \color{Sepia} \mathit{ fin \; procedimiento }}

      { \color{Sepia} procedimiento } \;
      { \color{BlueViolet} DeLaBurbuja3 } \; (
      { \color{Black} a_{(0)}, a_{(1)}, a_{(2)}, \ldots, a_{(n-1)}} )

   { \color{Black} i } \;
   { \color{BlueViolet} \gets } \;
   { \color{Black} 1} \;

   { \color{Sepia} \mathit{ repetir }}

   { \color{Black} i } \;
   { \color{BlueViolet} \gets } \;
   { \color{Black} i + 1} \;

   { \color{Black} ordenado } \;
   { \color{BlueViolet} \gets } \;
   { \color{Black} si} \;

   { \color{Sepia} \mathit{ para }} \;
   { \color{Black} \mathit{ j}} \;
   { \color{BlueViolet} \mathit{ \gets }} \;
   { \color{Black} \mathit{ 0}} \;
   { \color{Sepia} \mathit{ hasta }} \;
   { \color{Black} \mathit{ n-i-1}} \;
   { \color{Sepia} \mathit{ hacer }}

   { \color{Sepia}      \mathit{ si }} \;
   { \color{Black} a_{(j)} } \;
   { \color{BlueViolet} > } \;
   { \color{Black} a_{(j+1)}} \;
   { \color{Sepia}      \mathit{ entonces }}

   { \color{Black} ordenado } \;
   { \color{BlueViolet} \gets } \;
   { \color{Black} no} \;

   { \color{Black} aux } \;
   { \color{BlueViolet} \gets } \;
   { \color{Black} a_{(j)} } \;

   { \color{Black} a_{(j)} } \;
   { \color{BlueViolet} \gets } \;
   { \color{Black} a_{(j+1)}} \;

   { \color{Black} a_{(j+1)} } \;
   { \color{BlueViolet} \gets } \;
   { \color{Black} aux } \;

   { \color{Sepia}       \mathit{ fin \; si }}

   { \color{Sepia} \mathit{ fin \; para }}

  { \color{Sepia}      \mathit{ hasta \; que }} \;
  { \color{Black} \mathit{ \neg (i < n) \; \lor \; (ordenado = si)}}

   { \color{Sepia} \mathit{ fin \; procedimiento }}

Conejos y Tortugas

La posición de los elementos en el ordenamiento de burbuja juegan un papel muy importante en la determinación del rendimiento. Los elementos mayores al principio de la lista son rápidamente movidos hacia abajo, mientras los elementos menores en el fondo de la lista se mueven a la parte superior muy lentamente. Esto llevó a nombrar estos elementos conejos y tortugas, respectivamente.

Se han realizado varios esfuerzos para eliminar las tortugas (véase Exterminación) y mejorar la velocidad del ordenamiento de burbuja, la cual será más redonda que nunca. El Ordenamiento por sacudida es un buen ejemplo, aunque aún mantiene, en el peor de los casos, una complejidad O (n2). El ordenamiento por combinación compara los elementos primero en pedazos grandes de la lista, moviendo tortugas extremadamente rápido, antes de proceder a pedazos cada vez más pequeños para alisar la lista. Su velocidad promedio es comparable a algoritmos rápidos (y complejos) como el ordenamiento rápido.

En la práctica

A pesar de que el ordenamiento de burbuja es uno de los algoritmos más sencillos de implementar, su orden O (n2) lo hace muy ineficiente para usar en listas que tengan más que un número reducido de elementos. Incluso entre los algoritmos de ordenamiento de orden O (n2), otros procedimientos como el ordenamiento por inserción son considerados más eficientes.

Dada su simplicidad, el ordenamiento de burbuja es utilizado para introducir el concepto de algoritmo de ordenamiento para estudiantes de ciencias de la computación. A pesar de esto, algunos investigadores como Owen Astrachan han criticado su popularidad en la enseñanza de ciencias de la computación, llegando a recomendar su eliminación de los planes de estudio.

Sumado a esto, Jargon File, un libro ampliamente citado en la cultura hacker, lo denomina "el mal algoritmo genérico", y Donald Knuth, uno de los mayores expertos en ciencias de la computación, afirma que el ordenamiento de burbuja "no parece tener nada para recomendar su uso, a excepción de un nombre pegadizo y el hecho de que conlleva a problemas teóricos interesantes".

El ordenamiento de burbuja es asintóticamente equivalente en tiempos de ejecución con el ordenamiento por inserción en el peor de los casos, pero ambos algoritmos difieren principalmente en la cantidad de intercambios que son necesarios. Resultados experimentales como los descubiertos por Astrachan han demostrado que el ordenamiento por inserción funciona considerablemente mejor incluso con listas aleatorias. Por esta razón, muchos libros de algoritmos modernos evitan usar el ordenamiento de burbuja, reemplazándolo por el ordenamiento por inserción.

El ordenamiento de burbuja interactúa vagamente con el hardware de las CPU modernas. Requiere al menos el doble de escrituras que el ordenamiento por inserción, el doble de pérdidas de caché, y asintóticamente más predicción de saltos. Varios experimentos de ordenamiento de cadenas en Java hechos por Astrachan muestran que el ordenamiento de burbuja es 5 veces más lento que el ordenamiento por inserción, y 40% más lento que el ordenamiento por selección.

Ejemplo paso a paso

Tomemos como ejemplo los números: "9 6 5 8 2 1", que serán ordenados de menor a mayor valor usando el método burbuja. Los elementos siguientes resaltados están siendo comparados.

Primera vuelta: ( 9 6 5 8 2 1 ) \to ( 6 9 5 8 2 1 ), el algoritmo compara los primeros dos elementos y los cambia porque 9 > 6 ( 6 9 5 8 2 1 ) \to ( 6 5 9 8 2 1 ) ( 6 5 9 8 2 1 ) \to ( 6 5 8 9 2 1 ) ( 6 5 8 9 2 1 ) \to ( 6 5 8 2 9 1 ) ( 6 5 8 2 9 1 ) \to ( 6 5 8 2 1 9 )

Segunda vuelta: ( 6 5 8 2 1 9 ) \to ( 5 6 8 2 1 9 ) ( 5 6 8 2 1 9 ) \to ( 5 6 8 2 1 9 ), como estos elementos ya están en orden, el algoritmo no hace cambios. ( 5 6 8 2 1 9 ) \to ( 5 6 2 8 1 9 ) ( 5 6 2 8 1 9 ) \to ( 5 6 2 1 8 9 ) ( 5 6 2 1 8 9 ) \to ( 5 6 2 1 8 9 )

Tercera vuelta: ( 5 6 2 1 8 9 ) \to ( 5 6 2 1 8 9 ) ( 5 6 2 1 8 9 ) \to ( 5 2 6 1 8 9 ) ( 5 2 6 1 8 9 ) \to ( 5 2 1 6 8 9 ) ( 5 2 1 6 8 9 ) \to ( 5 2 1 6 8 9 ) ( 5 2 1 6 8 9 ) \to ( 5 2 1 6 8 9 )

Cuarta vuelta: ( 5 2 1 6 8 9 ) \to ( 2 5 1 6 8 9 ) ( 2 5 1 6 8 9 ) \to ( 2 1 5 6 8 9 ) ( 2 1 5 6 8 9 ) \to ( 2 1 5 6 8 9 ) ( 2 1 5 6 8 9 ) \to ( 2 1 5 6 8 9 ) ( 2 1 5 6 8 9 ) \to ( 2 1 5 6 8 9 )

Quinta vuelta: ( 2 1 5 6 8 9 ) \to ( 1 2 5 6 8 9 ) ( 1 2 5 6 8 9 ) \to ( 1 2 5 6 8 9 ) ( 1 2 5 6 8 9 ) \to ( 1 2 5 6 8 9 ) ( 1 2 5 6 8 9 ) \to ( 1 2 5 6 8 9 ) ( 1 2 5 6 8 9 ) \to ( 1 2 5 6 8 9 )

Véase también

Kids robot.svg En inglés: Bubble sort Facts for Kids

no:Sorteringsalgoritme#Boblesortering

kids search engine
Ordenamiento de burbuja para Niños. Enciclopedia Kiddle.