martes, 20 de marzo de 2012

7 Ordenación Externa


En la actualidad es muy común procesar tales volúmenes de información que los datos no pueden almacenar en las memorias principales de la computadora. Estos datos, organizados en archivos, se guardan en dispositivos de almacenamiento secundario tales como cintas, discos, etc.


El proceso de ordenar los datos almacenados en varios archivos se conoce con el nombre de fusión o mezcla, entendiendo por este concepto la combinación o intercalación de dos o más secuencias ordenadas en una única secuencia ordenada. Debe hacerse hincapié en que sólo se colocan en la memoria principal de la computadora los datos que se pueden acceder directamente.

6.2.1 Radix Ordenacion


El ordenamiento Radix (radix sort en inglés) es un algoritmo de ordenamiento que ordena enteros procesando sus dígitos de forma individual. Como los enteros pueden representar cadenas de caracteres (por ejemplo, nombres o fechas) y, especialmente, números en punto flotante especialmente formateados, radix sort no está limitado sólo a los enteros.
La mayor parte de los ordenadores digitales representan internamente todos sus datos como representaciones electrónicas de números binarios, por lo que procesar los dígitos de las representaciones de enteros por representaciones de grupos de dígitos binarios es lo más conveniente. Existen dos clasificaciones de radix sort: el de dígito menos significativo (LSD) y el de dígito más significativo (MSD). Radix sort LSD procesa las representaciones de enteros empezando por el dígito menos significativo y moviéndose hacia el dígito más significativo. Radix sort MSD trabaja en sentido contrario.
Las representaciones de enteros que son procesadas por los algoritmos de ordenamiento se les llamas a menudo "claves", que pueden existir por sí mismas o asociadas a otros datos. Radix sort LSD usa típicamente el siguiente orden: claves cortas aparecen antes que las claves largas, y claves de la misma longitud son ordenadas de forma léxica. Esto coincide con el orden normal de las representaciones de enteros, como la secuencia "1, 2, 3, 4, 5, 6, 7, 8, 9, 10". Radix sorts MSD usa orden léxico, que es ideal para la ordenación de cadenas de caracteres, como las palabras o representaciones de enteros de longitud fija. Una secuencia como "b, c, d, e, f, g, h, i, j, ba" será ordenada léxicamente como "b, ba, c, d, e, f, g, h, i, j". Si se usa orden léxico para ordenar representaciones de enteros de longitud variable, entonces la ordenación de las representaciones de los números del 1 al 10 será "1, 10, 2, 3, 4, 5, 6, 7, 8, 9", como si las claves más cortas estuvieran justificadas a la izquierda y rellenadas a la derecha con espacios en blanco, para hacerlas tan largas como la clave más larga, para el propósito de este ordenamiento.
Ejemplo.

Vector original:

V: 25      57      48      37     12    92     86    33

Asignamos los elementos en colas basadas en el dígito menos significativo de cada uno de ellos.
  • 0:
  • 1:
  • 2: 12, 92
  • 3: 33
  • 4:
  • 5: 25
  • 6: 86
  • 7: 57, 37
  • 8: 48
  • 9:
Después de la primera pasada, la ordenación queda:
V: 12   92   33   25   86   57   37   48
Colas basadas en el dígito más significativo.
  • 0:
  • 1: 12
  • 2: 25
  • 3: 33, 37
  • 4: 48
  • 5: 57
  • 6:
  • 7:
  • 8: 86
  • 9: 92
Lista ordenada:
V: 12,   25,   33,   37,   48,   57,   86,   92

6.2 Algoritmos Ordenamiento Distribucion.

Un problema que se presenta con frecuencia es el siguiente: "Ordenar un archivo con N registros cuyas llaves son enteros comprendidos entre 0 y M-1". SiM no es muy grande, se puede usar el algoritmo de distribución porconteo. La idea básica es contar el número de veces que serepite cada llave diferente y en una segunda pasada utilizar el conteo paraposicionar los registros en el archivo. 

6.1.3 Shell Sort Ordenacion


Ordenación por el método de Shell
El método de Shell es una versión mejorada del método de inserción directa. Recibe ese nombre en honor de su autor, Donald L. Shell, quien lo propuso en 1959. Este método tén se conoce comoinserción con incrementos decrecientes.

En el método de ordenación por inserción directa cada elemento se compara para su ubicación correcta en el arreglo con los elementos que se encuentran en su parte izquierda. Si el elemento a insertar es mas pequeño que el grupo de elementos que se encuentran a su izquierda, será necesario efectuar varias comparaciones antes de su ubicación.
Shell propone que las comparaciones entre elementos se efectúen con saltos de  mayor tamaño, pero con incrementos decrecientes; así, los elementos quedaran n nados en el arreglo más rápidamente. Para comprender mejor este algoritmo anlice siguiente caso.
Consideremos un arreglo que contenga 16 elementos. En primer lugar, se dividirán los elementos del arreglo en ocho grupos, teniendo en cuenta los elementos que se encuentran a ocho posiciones de distancia entre si y se ordenaran por separado.
Quedarán en el primer grupo los elementos (A[l], A[9]); en el segundo, (A[2], A[10]); en d i cero, (A[3], A[ll]), y así sucesivamente. Después de este primer paso se dividir los elementos del arreglo en cuatro grupos, teniendo en cuenta ahora que los  elementos se encuentren a cuatro posiciones de distancia entre si y se les ordenara por separado. Quedarán en el primer grupo los elementos (A[l], A[5], A[9], A[13]); en el segundo (A[2], A[6], A[10], A[14]), y así sucesivamente. En el tercer paso se dividirán los elementos del arreglo en grupos, tomando en cuenta los elementos que se encuentran ahora a dos posiciones de distancia entre si y nuevamente se les ordenara por separado. En el primer grupo quedarán (A[l], A[3], A[5], A[7], A[9], A[ll], A[13], A[15])  y en el segundo (A [2], A[4], A[6], A[8], A[10], A[12], A[14], A[16]).
Finalmente se agruparan y ordenaran los elementos de manera normal; es decir, de uno en uno. Se presenta a continuación un ejemplo.
Ejemplo. Supongamos que se desea ordenar los elementos que se encuentran en el arreglo unidimensional A utilizando el método de Shell.
A:    15    67    08    16   44   27    12   35    56   21    13    28    60   36    07    10
EJEMPLO PAG 351
A continuación se presenta el algoritmo de ordenación por el método de Shell.

Shell (A, A7)
{Este algoritmo permite ordenar los elementos de un arreglo unidimensional utilizando el método de Shell. A es un arreglo unidimensional de N elementos}
{INT, I y AUX son variables de tipo entero. BAND es una variable de tipo booleano}
1. Hacer INT <- N + 1
2. Mientras (INT > 1) Repetir
      Hacer INT <- parte entera (INT / 2) y BAND  <- VERDADERO
      2.1. Mientras (BAND = VERDADERO) Repetir
              Hacer BAND  <- FALSO  e  I -1
              2.1.1. Mientras ((I  +  INT)  <  N) Repetir
                     2.1.1.1. Si A[I > A[I + INT] entonces
                               Hacer AUX <- A[ I ],  A[ I ] <- A[ I + INT ],
                                       A[I + INT] <- AUX  y
                                       BAND <- VERDADERO
                     2.1.1.2. {Fin del condicional del paso 2.1.1.1}
                     Hacer  I <- I  + 1
              2.1.2. {Fin del ciclo del paso 2.1.1}
      2.2 {Fin del ciclo del paso 2.1}
3. {Fin del ciclo del paso 2}

Análisis de eficiencia del método de Shell
El análisis de eficiencia del método de Shell es un problema muy complicado y aun no resuelto. Hasta el momento no se ha podido establecer la mejor secuencia de incrementos cuando n es grande. Cabe recordar que cada vez que se propone una secuencia de intervalos, es necesario correr el algoritmo para analizar su tiempo de ejecución.

En 1969, Pratt descubrió que el tiempo de ejecución del algoritmo es del orden de n*(log n)2. Unas pruebas exhaustivas realizadas para obtener la mejor secuencia de intervalos cuando el número de elementos del arreglo es igual a 8 arrojaron como resultado que la mejor secuencia corresponde a un intervalo de 1, que no es más que el método de inserción directa estudiado previamente. Estas pruebas también determinaron que el menor número de movimientos se registraba con la secuencia 3, 2, 1. Cabe aclarar que las pruebas exhaustivas corresponden al análisis de (8!) posibilidades; es decir, 40 320 casos diferentes.
Para concluir con el análisis de eficiencia de método de Shell, se menciona que estudios de Peterson y Russell, en la Universidad de Stanford, en 1971, muestran que las mejores secuencias para valores de N comprendidos entre 100 y 60 000 son las que se presentan en la Lista de secuencias , donde k = 0, 1, 2, 3,...
Listas de Secuencias
  • l, 3, 5, 9, ... ,2k + l
  • 1, 3, 7, 15, ..., 2k -l
  • 1, 3, 5, 11, ...,(2k ± l)/3
  • 1, 4, 13, 40,..., (3k + l)/2

Ejemplo en C
int i, j, increment, temp;
increment = 3;
while (increment > 0)
{
      for (i=0; i < array_size; i++)
      {
            j = i;
            temp = numbers[i];
            while ((j >= increment) && (numbers[j-increment] > temp))
            {
                  numbers[j] = numbers[j - increment];
                  j = j - increment;
            }
            numbers[j] = temp;
      }
      if (increment/2 != 0)
      increment = increment/2;
      else
            if (increment == 1)
                  increment = 0;
            else
                  increment = 1;
      }

6.1.2 Quick Sort Ordenacion


Ordinación por el método quicksort
El método de ordenación quicksort es actualmente el más eficiente y veloz de los métodos de ordenación interna. Es también conocido como método rápido y de ordena por partición.  Este método es una mejora sustancial détodo de intercambio direct0  y se denomina quicksort rapido— por la velocidad con que ordena los elemento del arreglo. Su autor, C. A. Hoare, lo llamo así. La idea central de este algoritmo con en lo siguiente:
1.     Se toma un elemento X de una posición cualquiera del arreglo.
2.     Se trata de ubicar a X en la posición correcta del arreglo, de tal forma que todo los elementos que se encuentren a su izquierda sean menores o iguales a X y todos los se encuentren a su derecha sean mayores o iguales a X.
3.     Se repiten los pasos anteriores, pero ahora para los conjuntos de datos que se encuentran a la izquierda y a la derecha de la posición de X en el arreglo.
4.     El proceso termina cuando todos los elementos se encuentran en su posición correcta en el arreglo.
Se debe seleccionar, entonces, un elemento X cualquiera. En este caso se seleccionará A[l]. Se empieza a recorrer el arreglo de derecha a izquierda comparando si elementos son mayores o iguales a X. Si un elemento no cumple con esta condición, se intercambian aquellos y se almacena en una variable la posición del elemento intercambiado —se acota el arreglo por la derecha—. Se inicia nuevamente el recorrido. pero ahora de izquierda a derecha, comparando si los elementos son menores o iguales a X.
Si un elemento no cumple con esta condición, entonces se intercambian aquellos y se almacena en otra variable la posición del elemento intercambiado —se acota el arreglo por la izquierda—. Se repiten los pasos anteriores hasta que el elemento X encuentra su posición correcta en el arreglo. Analicemos a continuación el siguiente ejemplo.
Supongamos que se desea ordenar los elementos que se encuentran en el arreglo A utilizando el método.
A:    15    67    08    16   44    27    12    35
1.     Se selecciona A[1], por lo tanto, X <- 15.
2.     Se llevan a cabo las comparaciones que se muestran a continuación:
PRIMERA PASADA
Recorrido de derecha a izquierda
  • A[8]  >  X              (35 ≥ 15)              no hay intercambio
  • A[7]  >  X              (12 ≥15)               si hay intercambio
A:    12*   67   08   16   44    27    15*    35
Nota:  La cota con el * indica los elementos a intercambiar.
Recorrido de izquierda a derecha
  • A [2]   <  X            (67  ≤  15)             si hay intercambio
A:    12    15*    08    16    44    27    67*    35

SEGUNDA PASADA
Recorrido de derecha a izquierda
  • A[6]  >  X        (27 ≥ 15)       no hay intercambio
  • A[5]  >  X        (44 ≥ 15)       no hay intercambio
  • A[4]  >  X        (16 ≥ 15)       no hay intercambio
  • A[3]  >  X        (08 ≥ 15)       si hay intercambio
  
A:    12    08*    15*    16    44    27    67    35
Como el recorrido de izquierda a derecha se debería iniciar en la misma posición donde se encuentra el elemento X, el proceso termina ya que se detecta que el elemento X se encuentra en la posición correcta. Observe que los elementos que forman parte del primer conjunto son menores o iguales a X, y los del segundo conjunto son mayores o iguales a X.
A:    12   08    15    16    44    27    67    35
  • ler. Conjunto  conformados por los elementos 12, 08
  • posición de X en el elemento 15
  • 2o. conjunto conformados por los elementos 16, 44, 27, 67, 35
Este proceso de aprisionamiento aplicado para localizar la posición correcta de elemento X en el arreglo se repite cada vez que queden conjuntos formados por dos o más elementos. El método se puede aplicar de manera iterativa o recursiva.
El algoritmo de ordenación por el método quicksort en su versión recursiva es:

Rapido_recursivo (A, N)
{Este algoritmo ordena los elementos del arreglo unidimensional utilizando el método rápido. de manera recursiva. A es un arreglo unidimensional de N elementos}
1. Llamar al algoritmo Reduce_recursivo con 1 y N
Observe que el algoritmo Rapido_recursivo requiere para su funcionamiento otro algoritmo
Reduce_recursivo (INI, FIN, INI y FIN representan las posiciones del extremo izquierdo y derecho, respectivamente, del conjunto de elementos a ordenar}
{IZQ, DER, POS y AUX son variables de tipo entero. BAND es una variable de tipo
booleano}
1. Hacer IZQ <- INI, DER <- FIN, POS <- INI y BAND <- VERDADERO
2. Mientras (BAND = VERDADERO) Repetir
       Hacer BAND <- FALSO
       2.1. Mientras ((A[POS]  ≤  A[DER]) y (POS  ≠  DER)) Repetir
               Hacer DER <- DER - 1
       2.2. {Fin del ciclo del paso 2.1}
       2.3. Si (POS ≠ DER) entonces
               Hacer AUX <- A[POS], A[POS] <- A[DER],
                     A[DER] <- AUX y POS <- DER
               2.3.1. Mientras ((A[POS]  ≥  A[IZQ]) y (POS  ≠  IZQ)) Repetir
                          Hacer IZQ <- IZQ + 1
               2.3.2. {Fin del ciclo del paso 2.3.1}
               2.3.3. Si (POS  ≠  IZQ) entonces
                          Hacer BAND <- VERDADERO, AUX <- A[POS],
                                 A[POS] <- A [IZQ], A [IZQ] <- AUX y POS <- IZQ
               2.3.4. {Fin del condicional del paso 2.3.3}
       2.4. {Fin del condicional del paso 2.3}
3. {Fin del ciclo del paso 2}
4.  Si ((POS - 1) > INI) entonces
       Regresar a Reduce_recursivo con INI y (POS - 1) {Llamada recursiva}
5. {Fin del condicional del paso 4}
6. Si (FIN > (POS + 1)) entonces
       Regresar a Reduce_recursivo con (POS + 1) y FIN {Llamada recursiva}
6. {Fin del condicional del paso 6}

Aun cuando el algoritmo del quicksort presentado resulte claro, es posible aumentar su velocidad de ejecución eliminando las llamadas recursivas. La recursividad es un instrumento muy poderoso, pero la eficiencia de ejecución es un factor muy importante en un proceso de ordenación que es necesario cuidar y administrar muy bien. Estas llamadas recursivas se pueden sustituir utilizando pilas, dando lugar entonces a la interactividad.
Al utilizar la interactividad, se deben almacenar en las pilas los índices de los dos conjuntos de datos que falta tratar. Se utilizaran dos pilas, PILAMENOR y PILAMAYOR. En la primera se almacenara el extremo izquierdo y en la otra se almacenara el extremo derecho de los conjuntos de datos que falta tratar.
Los índices del primer conjunto quedaron almacenados en la primera posición de PILAMENOR y PILAMAYOR, respectivamente. La posición del extremo izquierdo del primer conjunto (1) en PILAMENOR y la del extremo derecho del mismo conjunto (2) en PILAMAYOR. Las posiciones de los extremos izquierdos y derecho del segundo conjunto (4 y 8) fueron almacenados en la cima de PILAMENOR y PILAMAYOR, respectivamente.

A continuación se presenta el algoritmo de ordenación por el método del quicksort utilizando interactividad en lugar de recursividad.

Rapido_iterativo (A, N)
{Este algoritmo ordena los elementos de un arreglo unidimensional utilizando el método rápido, de manera iterativa. A es un arreglo unidimensional de N elementos}
{TOPE, INI, FIN y POS son variables de tipo entero. PILAMENOR y PILAMAYOR son arreglos unidimensionales, que funcionan como pilas}
1. Hacer TOPE <- 1, PILAMENOR[TOPE] <- 1 y PILAMAYOR[TOPE] <- N
2. Mientras (TOPE > 0) Repetir
        Hacer INI <- PILAMENOR [TOPE],
                  FIN <- PILAMAYOR[TOPE]  y
                  TOPE <- TOPE - 1
         Llamar al algoritmo Reduce_iterativo con INI, FIN y POS.
         2.1. Si (INI < (POS - 1)) entonces
                Hacer TOPE <- TOPE + 1,
                       PILAMENOR[TOPE] <- INI  y
                       PILAMAYOR[TOPE] <- POS - 1
         2.2. {Fin del condicional del paso 2.1}
         2.3. Si (FIN > (POS + 1)) entonces
                 Hacer TOPE <- TOPE + 1,
                        PILAMENOR [TOPE] <- POS + 1  y
                        PILAMAYOR[TOPE] <- FIN
          2.4. {Fin del condicional del paso 2.3}
3. {Fin del ciclo del paso 2}
Note que el algoritmo Rapido_iterativo necesita para su funcionamiento de algoritmo, el cual se presenta a continuación.
Reduce_iterativo(I NI,FIN,POS) INI y FIN representan las posiciones de los extremos izquierdo y derecho, respectivamente, del conjunto de elementos a evaluar. POS es una variable donde se almacenara el resultado; este algoritmo IZQ, DER y AUX son variables de tipo entero. BAND es una variable de tipo booleano}
1. Hacer IZQ <- INI, DER <- FIN, POS <- INI y BAND <- VERDADERO
2. Mientras (BAND = VERDADERO) Repetir
       2.1. Mientras ((A[POS]  ≤  A [DER]) y (POS  ≠  DER)) Repetir
                Hacer DER <- DER -1
       2.2. {Fin del ciclo del paso 2.1}
       2.3. Si (POS = DER)
              entonces
                   Hacer BAND  <-  FALSO
                  si no
                        Hacer AUX <- A[POS], A[POS] <- A[DER],
                                   A[DER] <- AUX  y  POS <- DER
                   2.3.1. Mientras ((A[POS]  ≥ A[IZQ]) y (POS ≠ IZQ)) Repetir
                                   Hacer IZQ <- IZQ +1
                   2.3.2 {Fin del ciclo del paso 2.3.1}
                   2.3.3. Si (POS = IZQ)
                            entonces
                                    Hacer BAND  <- FALSO 
                            si no

                                     Hacer AUX <- A[POS], A[POS] <- A [IZQ],
                                    A[lZQ] <- AUX y POS <- IZQ
       2.3.4. {Fin del condicional del paso 2.3.3 }
       2.4. {Fin del condicional del paso 2.3}
3. {Fin del ciclo del paso 2}

Análisis de eficiencia del método quicksort
El método quicksort es el más rápido de ordenación interna que existe en la actualidad. Esto es sorprendente, porque el método tiene su origen en étodo de intercambio directo, el peor de todétodos directos. Diversos estudios realizados sobre su comportamiento demuestran que si se escoge en cada pasada el elemento que ocupa la posición central del conjunto de datos a analizar, el número de pasadas necesarias para ordenarlo es del orden de log n. Respecto del número de comparaciones, si el tamaño del arreglo es una potencia de 2, en la primera pasada realizara (n — 1) comparaciones, en la segunda (n - l)/2 comparaciones, pero en dos conjuntos diferentes, en la tercera realizara (n - l)/4 comparaciones, pero en cuatro conjuntos diferentes y así sucesivamente. Por lo tanto:
lo cual es lo mismo que:

C = (n - 1) + in - 1) + {n - 1) + ... + (n - 1)

Si se considera a cada uno de los componentes de la sumatoria como un término y el número de términos de la sumatoria es igual a m, entonces se tiene que:

C = (n - 1) * m

Considerando que el número de términos de la sumatoria (m) es igual al número de pasadas, y que este es igual a log n, la expresión anterior queda:
C = ( n –l )*log n
Sin embargo, encontrar el elemento que ocupe la position central del conjunto de datos que se van a analizar es una tarea difícil, ya que existen 1/n posibilidades de lograrlo. Además, el rendimiento medio del método es aproximadamente (2 * In 2) inferior al caso optimo, por lo que Hoare, el autor del método, propone como solución que el elemento se seleccione arbitrariamente o bien entre una muestra relativamente pequeña de elementos del arreglo.

El peor caso ocurre cuando los elementos del arreglo ya se encuentran ordenados, o bien cuando se encuentran en orden inverso.
Como conclusión, se puede afirmar que el tiempo promedio de ejecución del algoritmo es proporcional a (n * log n), O(n * log n). En el peor caso, el tiempo de ejecución es proporcional a n2, O(n2).
Ejemplo en C, recursivo
void swap(int l[], int i, int j)
{
      int dummy;
      dummy=l[j];
      l[j]=l[i];
      l[i]=dummy;
}
int partions(int l[],int low,int high)
{
      int prvotkey=l[low];
      while (low<high)
      {
            while (low<high && l[high]>=prvotkey)
            --high;
            swap(l,high,low);
            while (low<high && l[low]<=prvotkey)
            ++low;
            swap(l,high,low);
      }
      return low;
}
void qsort(int l[],int low,int high)
{
      int prvotloc;
      if(low<high)
      {
            prvotloc=partions(l,low,high);
            qsort(l,low,prvotloc);
            qsort(l,prvotloc+1,high);
      }
}
void quicksort(int l[],int n)
{
      qsort(l,0,n);
}

6.1.1 Ordenacion Burbuja


El método de intercambio directo, conocido coloquialmente como burbuja, es el utilizado entre los estudiantes principiantes de computación por su fácil comprensión y programación. Pero es preciso señalar que es quizás el método más ineficiente.

El método de intercambio directo puede trabajar de dos maneras diferentes: llevando los elementos más pequeños hacia la parte izquierda del arreglo o trasladando elementos más grandes hacia su parte derecha. La idea básica de este algoritmo con en comparar pares de elementos adyacentes e intercambiarlos entre si hasta que los elementos se encuentren ordenados. Se realizan (n - 1) pasadas transportando en cada una de el menor o mayor de elementos según sea el caso a su position ideal. Al final 1 (n - 1) pasadas los elementos del arreglo estarán ordenados.

Ejemplo. Supongamos que se desea ordenar las siguientes claves del arreglo unidimensional A, transportando en cada pasada el menor elemento hacia la parte izquierda del arreglo.
A: 15    67    08    16   44   27    12   35
Las comparaciones que se realizan son:
PRIMERA PASADA
  • A[7]  >  A[8]      (12 > 35)       no hay intercambio
  • A[6]  >  A[7]      (27 > 12)       si hay intercambio
  • A[5]  >  A[6]      (44 > 12)       si hay intercambio
  • A[4]  >  A[5]      (16 > 12)        si hay intercambio
  • A[3]  >  A[4]      (08 > 12)       no hay intercambio
  • A[2]  >  A[3]      (67 > 08)       si hay intercambio
  • A[1]  >  A[2]      (15 > 08)       si hay intercambio

Luego de la primera pasada el arreglo queda así:
A: 08   15    67    12    16   44   27    35
Observe que el elemento más pequeño, en este caso 08, fue situado en izquierda del arreglo.
SEGUNDA PASADA
  • A[7]  >  A[8]    (27 > 35)       no hay intercambio
  • A[6]  >  A[7]    (44 > 27)       si hay intercambio
  • A[5]  >  A[6]    (16 > 27)       no hay intercambio
  • A[4]  >  A[5]    (12 > 16)        no hay intercambio
  • A[3]  >  A[4]    (67 > 12)        si hay intercambio
  • A[2]  >  A[3]    (15 > 12)        si hay intercambio
Luego de la segunda pasada el arreglo queda así:
A:  08   12    15    67    16    27    44    35

y el segundo elemento más pequeño del arreglo, en este caso 12, fue situado en la segunda position.
El algoritmo de ordenación por el método de intercambio directo que transporta en cada pasada el menor elemento hacia la parte izquierda del arreglo es el siguiente:
Burbuja menor (A, N)

Este algoritmo ordena los elementos del arreglo unidimensional utilizando el método de la burbuja. Transporta en cada pasada el elemento más pequeño hacia la parte izquierda del arreglo. A es un arreglo unidimensional de N elementos I, J y AUX son variables de tipo entero
1. Repetir con I desde 2 hasta  N
     1.1  Repetir con J desde N hasta I
          1.1.1 Si A(J - 1) > A[J] entonces
                      Hacer AUX <- A[J - 1], A[J - 1] <- A[I] y A[I] <- AUX 
          1.1.2 Fin del condicional del paso 1.1.1
     1.2 Fin del ciclo del paso 1.1
2. Fin del ciclo del paso 1

Otra versión es hacer que el algoritmo de ordenación por el método de intercambio directo que transporta a cada pasada el elemento mayor hacia la parte derecha del arreglo es:
Burbuja mayor (A, N)   

El algoritmo ordena los elementos del arreglo unidimensional A. Transporta en cada pasada el elemento más grande hacia la parte derecha del arreglo. A es un arreglo de N elementos) I, J y AUX son variables de tipo entero   
1. Repetir con I  desde N-l hasta 1
     1.1. Repetir con J desde 1 hasta I
          1.1.1. Si A[J]  > A [J + 1] entonces
                          Hacer AUX <- A[J], A[J] <- A[J + 1] y A[J + 1] <- AUX
          1.1.2. Fin del condicional del paso 1.1.1       
     1.2. Fin del ciclo del paso 1.1
2. Fin del ciclo del paso 1

Análisis de eficiencia del método de intercambio directo
El número de comparaciones que se realizan en el método de la burbuja se puede contabilizar fácilmente. En la primera pasada se realizan (n - 1) comparaciones, en la segunda pasada (n - 2)comparaciones, en la tercera pasada (n - 3) comparaciones y así sucesivamente hasta llegar a 2 y 1 comparaciones entre claves, siendo n el número de elementos del arreglo. Por lo tanto, tenemos que el numero de comparaciones es:
Que es igual a =
Como ya se mencionado, se hace uso del principio de inducción matemática para desarrollar ciertas formulas.
Respecto del nmero de movimientos, estos dependen fundamentalmente de si el arreglo se encuentra ordenado, desordenado o en orden inverso. Los movimientos para cada uno de estos casos son:
  
Ahora bien, el tiempo necesario para ejecutar el algoritmo de la burbuja es proporcional a n^2 , O(n2), donde n es el número de elementos del arreglo.
Ejemplo en C
static void BurbujaEnteros(int[] A)
{
     int n = A.Length;
     int iaux;
     for (int i=0; i < n-1;i++)
     {
         for (int j = 0; j < n - i - 1;j++ )
          {
               if (A[j] > A[j + 1])
               {
                    iaux = A[j];
                   A[j] = A[j + 1];
                    A[j + 1] = iaux;
               }
          }
     }
}

6.1 Algoritmos Ordenamiento por Intercambio

Los ordenamientos realizados sobre estructurasdedatos residentes en memoria principal se conocen como ordenamientosinternos,mientras que los ordenamientos realizados sobre estructuras dedatos residentesen archivos se conocen como ordenamientos externos.