Está en la página 1de 15

UAA Sistemas Electrnicos

Estructura de Datos

Serna

3
3.1

Mtodos de Ordenamiento
Tipos de Ordenamiento

La ordenacin o clasificacin de datos consiste en la disposicin de los mismos de acuerdo con algn valor o caracterstica. Por ejemplo, cada elemento de una agenda telefnica tiene un campo nombre, un campo direccin y un campo nmero telefnico. Por lo regular los datos en la agenda se encuentran organizados en un orden de la A la Z. De la misma forma un lista vector de datos se dice que esta ordenado de manera ascendente, si X [ i ] <= X [ i +1] y, por otro lado, se dice que esta ordenado de manera descendente s X [ i ] >= X [ i +1]. El proceso de ordenacin es uno de los mecanismos ms interesantes cuando llega el momento de mostrar que existen mltiples soluciones para un mismo problema, y que cada solucin algortmica tiene sus propias ventajas y desventajas. Una forma de medir la eficiencia de un algoritmo de esta clase, es verificar el nmero de comparaciones entre valores clave, adems del nmero de movimientos que se tengan que realizar entre elementos (intercambios) de la lista. Los mtodos de ordenamiento que trabajan con estructuras de datos residentes en memoria principal se denominan Ordenamientos Internos, mientras que las implementaciones que utilizan estructuras de datos residentes en archivos se conocen como Ordenamientos externos.

3.2

Ordenamiento Interno

Los mtodos de ordenamiento interno trabajan en memoria principal y sus implementaciones son muy variadas, de manera que la eleccin del algoritmo adecuado debe realizarse con criterios de eficiencia (tiempo y ejecucin) y en funcin de la memoria disponible. Dividiremos los mtodos en dos grandes grupos: Directos (burbuja, seleccin e insercin). Logartmicos (Shell sort, Merge sort, Heap sort, Quick sort, Radix).

En el caso de listas pequeas, los mtodos directos se desempean de manera relativamente eficientes, ya que la codificacin del algoritmo correspondiente no es compleja. Su uso es muy frecuente. Sin embargo, en arreglos grandes las ordenaciones directas resultan ineficientes y se necesitara un mtodo logartmico para su solucin.

3.2.1 Ordenacin por intercambio (burbuja) Es uno de los mtodos relativamente ms sencillo e intuitivo, pero tambin resulta ser muy ineficiente. Se basa en la ordenacin por cambio, y recibe su nombre de la semejanza con las burbujas de un depsito de agua donde cada burbuja busca su propio nivel. Los pasos a efectuar en el caso de una ordenacin ascendente (en el caso de la ordenacin descenderte solo habra que cambiar el signo de comparacin) son: 1. Comparar el primer y segundo elemento, intercambiarlos si el primero es mayor que el segundo; luego se compara el primero con el tercero, intercambindose en caso necesario, y el proceso se repite hasta llegar al ltimo elemento. De este modo, tras la primera iteracin la casilla primera conservara el elemento ms pequeo de esa iteracin.

UAA Sistemas Electrnicos

Estructura de Datos

Serna

2. Se repite el paso anterior, pero ahora con el segundo y tercero, en caso de ser necesario se intercambian, y as hasta llegar a comparar el segundo con el ultimo. Consideremos el siguiente ejemplo. Se cuenta con un vector de 6 posiciones donde se inicia una lista de nmeros { 7, 2, 8, 3, 5, 1 }, la cual ser ordenada en forma ascendente { 1, 2, 3, 5, 7, 8 }, observe como se declara una variable constante entera llamada n la cual tiene un valor de 6, enseguida se declara un vector de tipo entero que contendr una cantidad n de casillas, en este caso 6, declaramos tambin las variables i y j que nos ayudaran a desplazarnos entre casilla y casilla para hacer las comparaciones. Y finalmente la variable tem, almacenara temporalmente el valor a intercambiar entre las casillas que lo necesiten. El proceso sera de la siguiente manera: 1ra iteracin, i permanece fijo en la casilla 0 y j se incrementa hasta llegar al ltimo elemento: { 7, 2, 8, 3, 5, 1 } j = 1, intercambio generando { 2, 7, 8, 3, 5, 1 }, enseguida { 2, 7, 8, 3, 5, 1 } j = 2, no genera intercambio { 2, 7, 8, 3, 5, 1 } j = 3, no genera intercambio { 2, 7, 8, 3, 5, 1 } j = 4, no genera intercambio { 2, 7, 8, 3, 5, 1 } j = 5, intercambio generando { 1, 7, 8, 3, 5, 2 }, termina iteracin 2da iteracin, i permanece fijo en la casilla 1 y j se incrementa hasta llegar al ltimo elemento: { 1, 7, 8, 3, 5, 2 } j = 2, no genera intercambio { 1, 7, 8, 3, 5, 2 } j = 3, intercambio generando { 1, 3, 8, 7, 5, 2 }, enseguida { 1, 3, 8, 7, 5, 2 } j = 4, no genera intercambio { 1, 3, 8, 7, 5, 2 } j = 5, intercambio generando { 1, 2, 8, 7, 5, 3 }, termina iteracin 3ra iteracin, i permanece fijo en la casilla 2 y j se incrementa hasta llegar al ltimo elemento: { 1, 2, 8, 7, 5, 3 } j = 3, intercambio generando { 1, 2, 7, 8, 5, 3 } { 1, 2, 7, 8, 5, 3 } j = 4, intercambio generando { 1, 2, 5, 8, 7, 3 } { 1, 2, 5, 8, 7, 3 } j = 5, intercambio generando { 1, 2, 3, 8, 7, 5 }, termina iteracin 4ta iteracin, i permanece fijo en la casilla 3 y j se incrementa hasta llegar al ltimo elemento: { 1, 2, 3, 8, 7, 5 } j = 4, intercambio generando { 1, 2, 3, 7, 8, 5 } { 1, 2, 3, 7, 8, 5 } j = 5, intercambio generando { 1, 2, 3, 5, 8, 7 }, termina iteracin 5ta iteracin, i permanece fijo en la casilla 4 y j se incrementa hasta llegar al ltimo elemento: { 1, 2, 3, 5, 8, 7 } j = 5, intercambio generando { 1, 2, 3, 5, 7, 8 }, termina proceso void burbuja(int * v, int n) /*** cdigo en C++ ***/ { /* ordenamiento de burbuja */ for (int i = 0; i < n-1; i++) for (int j = i + 1; j < n; j++) { if ( v[i] > v[j] ) { //realiza la comparacin int tem = v[i]; //si es cierta intercambia los datos v[i] = v[j]; v[j] = tem; } } } Algoritmo de Burbuja mejorado Existe una versin mejorada de dicho algoritmo en donde se integra una variable que funge como switch (bandera) que permite detectar el momento en que ya no se presenten mas intercambios aunque su mejora no suele ser tan importante pues el algoritmo sigue comportndose como una 2 ordenacin cuadrtica O(n ).

UAA Sistemas Electrnicos

Estructura de Datos

Serna

void burbuja(int *v, int n) /*** cdigo en C++ ***/ { bool sw = true; int li = 0; do { li++; sw = true; for (int i = 0; i < n - li; i++) { if ( v[i] > v[i+1] ) { // compara los valores // intercambia los datos int tem = v[i]; v[i] = v[i+1]; v[i+1] = tem; sw = false; } } } while(!sw); }

3.2.2 Mtodo de seleccin La idea bsica es encontrar el elemento ms pequeo (grande), en orden ascendente de la lista, e intercambiarlo con el elemento que ocupa la primera posicin en la lista, a continuacin se busca el siguiente elemento ms pequeo y se transfiere a la segunda posicin. Se repite el proceso hasta que el ltimo elemento ha sido transferido a su posicin correcta. El algoritmo de ordenacin depende a su vez del algoritmo necesario para localizar el componente mayor (menor) de un array. Es un proceso muy similar al mtodo de la burbuja pero haciendo ms eficiente la bsqueda y evitando intercambios innecesarios. Consideremos el mismo arreglo del ejemplo anterior { 7, 2, 8, 3, 5, 1 }. El proceso sera de la siguiente manera: 1ra iteracin, i permanece fijo en la casilla 0 y j se incrementa hasta llegar al ltimo elemento: { 7, 2, 8, 3, 5, 1 } k = 0, j = 1, cambio k = j ya que en j esta el menor { 7, 2, 8, 3, 5, 1 } k = 1, j = 2, no genera cambio { 7, 2, 8, 3, 5, 1 } k = 1, j = 3, no genera cambio { 7, 2, 8, 3, 5, 1 } k = 1, j = 4, no genera cambio { 7, 2, 8, 3, 5, 1 } k = 1, j = 5, cambio k = j ya que en j esta el menor, genera { 1, 2, 8, 3, 5, 7 } 2da iteracin, i permanece fijo en la casilla 1 y j se incrementa hasta llegar al ltimo elemento: { 1, 2, 8, 3, 5, 7 } k = 1, j = 2 - 5, no genera cambios 3ra iteracin, i permanece fijo en la casilla 2 y j se incrementa hasta llegar al ltimo elemento: { 1, 2, 8, 3, 5, 7 } k = 2, j = 3, cambio k = j ya que en j esta el menor { 1, 2, 8, 3, 5, 7 } k = 3, j = 4, no genera cambio { 1, 2, 8, 3, 5, 7 } k = 3, j = 5, no genera cambio, termina el ciclo, genera { 1, 2, 3, 8, 5, 7 } 4ta iteracin, i permanece fijo en la casilla 3 y j se incrementa hasta llegar al ltimo elemento: { 1, 2, 3, 8, 5, 7 } k = 3, j = 4, cambio k = j ya que en j esta el menor { 1, 2, 3, 8, 5, 7 } k = 4, j = 5, no genera cambio, termina el ciclo, genera { 1, 2, 3, 5, 8, 7 } 5ta iteracin, i permanece fijo en la casilla 4 y j se incrementa hasta llegar al ltimo elemento: { 1, 2, 3, 5, 8, 7 } k = 4, j = 5, cambio k = j ya que en j esta el menor, genera { 1, 2, 3, 5, 7, 8 }

UAA Sistemas Electrnicos

Estructura de Datos

Serna

void seleccion( int * v, int n) /*** cdigo en C++ ***/ { /* ordenamiento de seleccion */ for (int i = 0, j = 0, k = 0; i < n-1; i++) { k = i; for (j = i+1; j < n; j++) if ( v[k] > v[j] ) k = j; int tem = v[i]; v[i] = v[k]; v[k] = tem; } }

3.2.3 Mtodo de Insercin Este mtodo tambin se denomina mtodo del jugador de cartas, por la semejanza con la forma de clasificar las cartas de una baraja, insertando cada carta en el lugar adecuado. El algoritmo ordena los dos primeros elementos de la lista, a continuacin el tercer elemento se inserta en la posicin que corresponda, el cuarto se inserta en la lista de tres elementos, y as sucesivamente. Este proceso continua hasta que la lista este totalmente ordenada. Sea una lista A[1], A[2], ... A[n]. Los pasos a dar para una ordenacin ascendente son: 1. Ordenar A[1] y A[2]. 2. Comparar A[3] con A[2], si A[3] es mayor o igual a que A[2], sigue con el siguiente elemento si no se compara A[3] con A[1]; si A[3] es mayor o igual que A[1], insertar A[3] entre A[1] yA[2]. Si A[3] es menor que A[1], entonces transferir A[3] a A[1], A[1] a A[2] y A[2] a A[3]. 3. Se suponen ordenados los n-1 primeros elementos y corresponde insertar el n-simo elemento. Si A[m] es mayor que A[k] (con K = 1, 2, ..., m-1), se debe correr una posicin A[k+1], ... A[m-1] y almacenar A[m] en la posicin k+1. Consideremos el mismo arreglo del ejemplo anterior { 7, 2, 8, 3, 5, 1 }. El proceso sera de la siguiente manera: 1ra iteracin, i permanece fijo en la casilla 1 y j se decrementa mientras el elemento es menor a j: { 7, 2, 8, 3, 5, 1 } tem = 2, j = 0, mientras j >= 0 y tem < 7, { 7, 7, 8, 3, 5, 1 }, j se decrementa en 1 { 7, 7, 8, 3, 5, 1 } tem = 2, j = -1, mientras j >=0, rompe mientras, tem ingresa { 2, 7, 8, 3, 5, 1 } 2da iteracin, i permanece fijo en la casilla 2 y j se decrementa mientras el elemento es menor a j: { 2, 7, 8, 3, 5, 1 } tem = 8, j = 1, mientras j >= 0 y tem < 7, rompe mientras { 2, 7, 8, 3, 5, 1 } 3ra iteracin, i permanece fijo en la casilla 3 y j se decrementa mientras el elemento es menor a j: { 2, 7, 8, 3, 5, 1 } tem = 3, j = 2, mientras j >= 0 y tem < 8, { 2, 7, 8, 8, 5, 1 }, j se decrementa en 1 { 2, 7, 8, 8, 5, 1 } tem = 3, j = 1, mientras j >= 0 y tem < 7, { 2, 7, 7, 8, 5, 1 }, j se decrementa en 1 { 2, 7, 7, 8, 5, 1 } tem = 3, j = 0, mientras j >= 0 y tem < 2, rompe, tem ingresa { 2, 3, 7, 8, 5, 1 } 4ta iteracin, i permanece fijo en la casilla 4 y j se decrementa mientras el elemento es menor a j: { 2, 3, 7, 8, 5, 1 } tem = 5, j = 3, mientras j >= 0 y tem < 8, { 2, 3, 7, 8, 8, 1 }, j se decrementa en 1 { 2, 3, 7, 8, 8, 1 } tem = 5, j = 2, mientras j >= 0 y tem < 7, { 2, 3, 7, 7, 8, 1 }, j se decrementa en 1 { 2, 3, 7, 7, 8, 1 } tem = 5, j = 1, mientras j >= 0 y tem < 3, rompe, tem ingresa { 2, 3, 5, 7, 8, 1 } 5ta iteracin, i permanece fijo en la casilla 5 y j se decrementa mientras el elemento es menor a j: { 2, 3, 5, 7, 8, 1 } tem = 1, j = 4, mientras j >= 0 y tem < 8, { 2, 3, 5, 7, 8, 8 }, j se decrementa en 1 { 2, 3, 5, 7, 8, 8 } tem = 1, j = 3, mientras j >= 0 y tem < 7, { 2, 3, 5, 7, 7, 8 }, j se decrementa en 1

UAA Sistemas Electrnicos

Estructura de Datos

Serna

{ 2, 3, 5, 7, 7, 8 } tem { 2, 3, 5, 5, 7, 8 } tem { 2, 3, 3, 5, 7, 8 } tem { 2, 2, 3, 5, 7, 8 } tem

= 1, j = 2, mientras j >= 0 y tem < 5, { 2, 3, 5, 5, 7, 8 }, j se decrementa en 1 = 1, j = 1, mientras j >= 0 y tem < 3, { 2, 3, 3, 5, 7, 8 }, j se decrementa en 1 = 1, j = 0, mientras j >= 0 y tem < 2, { 2, 2, 3, 5, 7, 8 }, j se decrementa en 1 = 1, j = -1, mientras j >= 0, rompe mientras, tem ingresa { 1, 2, 3, 5, 7, 8 }

void insercion( int * v, int n) /*** cdigo en C++ ***/ { /* ordenamiento de insercion */ for (int i = 1, j = 0; i < n; i++) { int tem = v[i]; j = i - 1; while ( j >= 0 && tem < v[j]) { v[j+1] = v[j]; j--; } v[j+1] = tem; } }

3.2.4

Ordenacin Shell

Shell sort lleva este nombre en honor a su inventor, Donald Shell, que lo public en 1959. La idea bsica de este mtodo es distribuir el arreglo de manera que se genere una matriz de valores donde cada elemento es comparado de manera adyacente empleando un mecanismo de insercin directa simple, dicho rango que genera grupos de manera matricial que es reducido gradualmente hasta estabilizarse en un valor uniforme de 1. En el mtodo de ordenacin por insercin directa es empleado en cada sub grupo de manera que cada elemento se compara para su ubicacin correcta en el arreglo con los elementos que se encuentran en su parte izquierda. Si el elemento a insertar es ms pequeo que el grupo de elementos que se encuentran a su izquierda, ser necesario efectuar varias comparaciones antes de su ubicacin. Shell propone que las comparaciones entre elementos se efecten con saltos de mayor tamao, pero con incrementos decrecientes; as, los elementos quedaran ordenados ms rpidamente. El algoritmo para Shell sort seria el siguiente. Algunos autores suponen una secuencia geomtrica de decremento (2.2) que permite una distribucin presumiblemente ms razonable para el acomodo de los grupos de elementos a comparar. El algoritmo emplea un arreglo a de 0 a n-1: inc = round(n/2) mientras inc > 0 { para i = inc hasta n 1 { temp = a[i] j = i mientras j = inc && a[j - inc] > temp { a[j] = a[j - inc] j = j inc } a[j] = temp } inc = round(inc / 2.2) }

UAA Sistemas Electrnicos

Estructura de Datos

Serna

Consideremos el siguiente ejemplo, tenemos una lista de nmeros como 13 14 94 33 82 25 59 94 65 23 45 27 73 25 39 10. Si comenzamos con un tamao de paso de 5, podramos visualizar esto dividiendo la lista de nmeros en una tabla con 5 columnas. Esto quedara as: 13 14 94 33 82 25 59 94 65 23 45 27 73 25 39 10

Entonces ordenamos cada columna, lo que nos da 10 14 73 25 23 13 27 94 33 39 25 59 94 65 82 45

Cuando lo leemos de nuevo como una nica lista de nmeros, obtenemos 10 14 73 25 23 13 27 94 33 39 25 59 94 65 82 45. Aqu, el 10 que estaba en el extremo final, se ha movido hasta el extremo inicial. Esta lista es entonces de nuevo ordenada usando un ordenamiento con un espacio de 3 posiciones, y despus un ordenamiento con un espacio de 1 posicin (ordenamiento por insercin simple). 10 14 73 Generando 10 14 13 Y finalmente 10 14 13 25 23 33 27 25 59 39 65 73 45 94 82 94 10 13 14 23 25 25 27 33 39 45 59 65 73 82 94 94 25 23 33 27 25 59 39 65 73 45 94 82 94 25 23 13 27 94 33 39 25 59 94 65 82 45

void shell_sort(int A[], int size) /*** cdigo en C++ ***/ { int j, temp; int incrmnt = size/2; while (incrmnt > 0) { for (int i = incrmnt; i < size; i++) { j = i; temp = A[i]; while ((j >= incrmnt) && (A[j-incrmnt] > temp)) { A[j] = A[j - incrmnt]; j = j - incrmnt; } A[j] = temp; } incrmnt /= 2; } }

3.2.5

Ordenacin por Mezcla (Merge Sort)

Fue desarrollado en 1945 por John Von Neumann. Conceptualmente, el ordenamiento por mezcla funciona de la siguiente manera: 1. Si la longitud de la lista es 0 1, entonces ya est ordenada. En otro caso: 2. Dividir la lista desordenada en dos sublistas de aproximadamente la mitad del tamao.

UAA Sistemas Electrnicos

Estructura de Datos

Serna

3. Ordenar cada sublista recursivamente aplicando el ordenamiento por mezcla. 4. Mezclar las dos sublistas en una sola lista ordenada. El ordenamiento por mezcla incorpora dos ideas principales para mejorar su tiempo de ejecucin: Una lista pequea necesitar menos pasos para ordenarse que una lista grande. Se necesitan menos pasos para construir una lista ordenada a partir de dos listas tambin ordenadas, que a partir de dos listas desordenadas. Por ejemplo, slo ser necesario entrelazar cada lista una vez que estn ordenadas. A continuacin se describe el algoritmo en pseudocdigo (se advierte de que no se incluyen casos especiales para vectores vacos, una implementacin en un lenguaje de programacin real debera tener en cuenta estos detalles): funcion merge_sort( list m ) if length(m) 1 return m var list left, right, result var integer middle = length(m) / 2 for each x in m up to middle add x to left for each x in m after middle add x to right left = merge_sort(left) right = merge_sort(right) result = merge(left, right) return result funcion merge( list left, right) var list result while length(left) > 0 or length(right) > 0 if length(left) > 0 and length(right) > 0 if first(left) first(right) append first(left) to result left = rest(left) else append first(right) to result right = rest(right) else if length(left) > 0 append first(left) to result left = rest(left) else if length(right) > 0 append first(right) to result right = rest(right) end while return result Considere el siguiente ejemplo con una lista { 5, 2, 4, 6, 1, 3, 2, 6 }, la lista es dividida en la primera de las dos llamadas a merge con { 5, 2, 4, 6 }, despus nuevamente es dividida en { 5, 2 }, se intercala obteniendo { 2, 5 }, la segunda llamada recupera { 4, 6 } y se intercalan para obtener { 2, 4, 5, 6 }. Con la mitad { 1, 3, 2, 6 } ocurre la misma reduccin de elementos tras las llamadas intercalando finalmente la salida para obtener { 1, 2, 2, 3, 4, 5, 6, 6 }.

UAA Sistemas Electrnicos

Estructura de Datos

Serna

La siguiente Figura1 describe mejor el proceso de retro-seguimiento (backtrack) que construye la lista ordenada una vez que la recursividad alcanza su caso base.

Figura 1 void intercala(int *a, int na, int *b, int nb, int *v)/* cdigo en C++ */ { int xa=0, xb=0, xv=0; while (xa < na && xb < nb) { if (a[xa] < b[xb]) v[xv] = a[xa++]; else v[xv] = b[xb++]; xv++; } while (xa < na) v[xv++] = a[xa++]; while (xb < nb) v[xv++] = b[xb++]; } void merge(int v[], int n) { int *a,*b, na,nb, x,y; if ( n > 1 ) { if (n%2 == 0) na = nb = (int) n / 2; else { na = (int) n / 2; nb = na + 1; } a = new int [na]; b = new int [nb]; for(x = 0; x < na; x++) a[x] = v[x]; for(y = 0; y < nb; x++,y++) b[y] = v[x]; merge(a, na);

UAA Sistemas Electrnicos

Estructura de Datos

Serna

merge(b, nb); intercala(a, na, b, nb, v); delete a, b; } }

3.2.6

Ordenacin por particin e intercambio (Quick Sort)

Es un algoritmo relativamente eficiente y representa una mejora sustancial al mtodo de intercambio directo. El algoritmo es el siguiente: 1. Elegir un elemento de la lista de elementos a ordenar (pivote). 2. Resituar los dems elementos de la lista a cada lado del pivote, de manera que a un lado queden todos los menores que l, y al otro los mayores. Los elementos iguales al pivote pueden ser colocados tanto a su derecha como a su izquierda, dependiendo de la implementacin deseada. En este momento, el pivote ocupa exactamente el lugar que le corresponder en la lista ordenada. 3. La lista queda separada en dos sub-listas, una formada por los elementos a la izquierda del pivote, y otra por los elementos a su derecha. 4. Repetir este proceso de forma recursiva para cada sub-lista mientras stas contengan ms de un elemento. Una vez terminado este proceso todos los elementos estarn ordenados. Como se puede suponer, la eficiencia del algoritmo depende de la posicin en la que termine el pivote elegido. En el mejor caso, el pivote termina en el centro de la lista, dividindola en dos sublistas de igual tamao. En este caso, el orden de complejidad del algoritmo es O(n log n). En el peor caso, el pivote termina en un extremo de la lista. El orden de complejidad del algoritmo es entonces de O(n). El peor caso depender de la implementacin del algoritmo, aunque habitualmente ocurre en listas que se encuentran ordenadas, o casi ordenadas. Pero principalmente depende del pivote, por ejemplo el algoritmo implementado toma como pivote siempre el primer elemento del arreglo, y el arreglo que le pasamos est ordenado, siempre va a generar a su izquierda un arreglo vaco, lo que es ineficiente. En el siguiente ejemplo se marcan el pivote y los ndices i y j con las letras p, i y j respectivamente. Comenzamos con la lista completa. El elemento pivote ser el 4: 5 - 3 - 7 - 6 - 2 - 1 - 4 p Comparamos con el 5 por la izquierda y el 1 por la derecha. 5 - 3 - 7 - 6 - 2 - 1 - 4 i j p 5 es mayor que 4 y 1 es menor. Intercambiamos: 1 - 3 - 7 - 6 - 2 - 5 - 4 i j p

UAA Sistemas Electrnicos

Estructura de Datos

Serna

Avanzamos por la izquierda y la derecha: 1 - 3 - 7 - 6 - 2 - 5 - 4 i j p 3 es menor que 4: avanzamos por la izquierda. 2 es menor que 4: nos mantenemos ah. 1 - 3 - 7 - 6 - 2 - 5 - 4 i j p 7 es mayor que 4 y 2 es menor: intercambiamos. 1 - 3 - 2 - 6 - 7 - 5 - 4 i j p Avanzamos por ambos lados: 1 - 3 - 2 - 6 - 7 - 5 - 4 iyj p En este momento termina el ciclo principal, porque los ndices se cruzaron. Ahora intercambiamos lista[i] con lista[sup]. 1 - 3 - 2 - 4 - 7 - 5 - 6 p Aplicamos recursivamente a la sub-lista de la izquierda (ndices 0 - 2). Tenemos lo siguiente: 1 - 3 - 2 1 es menor que 2: avanzamos por la izquierda. 3 es mayor: avanzamos por la derecha. Como se intercambiaron los ndices termina el ciclo. Se intercambia lista[i] con lista[sup]: 1 - 2 - 3 El mismo procedimiento se aplicar a la otra sub-lista. Al finalizar y unir todas las sub-listas queda la lista inicial ordenada en forma ascendente. 1 - 2 - 3 - 4 - 5 - 6 - 7

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; int dummy; dummy=l[low]; l[low]=l[high]; l[high]=dummy; }

10

UAA Sistemas Electrnicos

Estructura de Datos

Serna

} 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); }

3.2.7

Ordenacin basado en comparaciones (Heap Sort)

Es una variante del algoritmo de seleccin, El ordenamiento por montculos (Heap sort) es un algoritmo de ordenacin no recursivo, no estable, con complejidad computacional O(n log n). Este algoritmo consiste en almacenar todos los elementos del vector a ordenar en un montculo (heap), y luego extraer el nodo que queda como nodo raz del montculo (cima) en sucesivas iteraciones obteniendo el conjunto ordenado. Basa su funcionamiento en una propiedad de los montculos, por la cual, la cima contiene siempre el menor elemento (o el mayor, segn se haya definido el montculo) de todos los almacenados en l. El significado de heap en computacin es el de una cola de prioridades (priority queue). Tiene las siguientes caractersticas: Un heap es un arreglo de n posiciones ocupado por los elementos de la cola. Se mapea un rbol binario de tal manera en el arreglo que el nodo en la posicin i es el padre de los nodos en las posiciones (2*i) y (2*i+1). El valor en un nodo es mayor o igual a los valores de sus hijos. Por consiguiente, el nodo padre tiene el mayor valor de todo su subrbol

heap

arreglo

11

UAA Sistemas Electrnicos

Estructura de Datos

Serna

Heap Sort consiste esencialmente en: convertir el arreglo en un heap construir un arreglo ordenado de atrs hacia adelante (mayor a menor) repitiendo los siguientes pasos: o sacar el valor mximo en el heap (el de la posicin 1) o poner ese valor en el arreglo ordenado o reconstruir el heap con un elemento menos utilizar el mismo arreglo para el heap y el arreglo ordenado.

3.3

Ordenamiento Externo

La ordenacin de archivos se lleva a cabo cuando el volumen de los datos a tratar es demasiado grande y los mismos no caben en la memoria principal de la computadora. Al ocurrir esta situacin no pueden aplicarse los mtodos de ordenacin interna, de modo que debe pensarse en otro tipo de algoritmos para ordenar datos almacenados en archivos. Por ordenacin de archivos se entiende, entonces, la ordenacin o clasificacin de stos, ascendente o descendentemente, de acuerdo con un campo determinado al que se denominar campo clave. La principal desventaja de esta ordenacin es el tiempo de ejecucin, debido a las sucesivas operaciones de entrada y salida. Los dos mtodos de ordenacin externa ms importantes son los basados en la mezcla directa y en la mezcla equilibrada.

3.3.1

Ordenacin por mezcla directa

El mtodo de ordenacin por mezcla directa es probablemente el ms utilizado por su fcil comprensin. La idea central de este algoritmo consiste en la realizacin sucesiva de una particin y una fusin que produce secuencias ordenadas de longitud cada vez mayor. En la primera pasada la participacin es de longitud 1 y la fusin o mezcla produce secuencias ordenadas de longitud 4. Este proceso se repite hasta que la longitud de la secuencia para la particin sea mayor o igual que la longitud de la secuencia para la particin sea mayor o igual que el nmero de elementos del archivo original. Supngase que se desean ordenar las claves del archivo F. Para realizar tal actividad se utilizan dos archivos auxiliares a los que se les denominar F1 y F2. F: 09 75 14 68 29 17 31 25 04 05 13 18 72 46 61 PRIMERA PASADA Particin en secuencias de longitud 1. F1: 09 14 29 31 04 13 72 61

12

UAA Sistemas Electrnicos

Estructura de Datos

Serna

F2: 75 68 17 25 05 18 46 Fusin en secuencias de longitud 2. F1: 09 75 14 68 17 29 25 31 04 05 13 18 46 72 61 SEGUNDA PASADA Particin en secuencias de longitud 2. F1: 09 75 17 29 04 05 46 72 F2: 14 68 25 31 13 18 61 Fusin en secuencias de longitud 4. F1: 09 14 68 75 17 25 29 31 04 05 13 18 46 61 72 TERCERA PASADA Particin en secuencias de longitud 4. F1: 09 14 68 75 04 05 13 18 F2: 17 25 29 31 46 61 72 Fusin en secuencias de longitud 8. F1: 09 14 75 25 29 31 68 75 04 05 13 18 46 61 72 CUARTA PASADA Particin en secuencias de longitud 8. F1: 09 14 17 25 29 31 68 75 F2: 04 05 13 18 46 61 72 Fusin en secuencias de longitud 16. F1: 04 05 09 13 14 17 18 25 29 31 46 61 68 72 75

3.3.2

Ordenacin por mezcla equilibrada

El mtodo de ordenacin por mezcla equilibrada, conocido tambin con el nombre de mezcla natural, es una optimizacin del mtodo de mezcla directa. La idea central de este mtodo consiste en realizar las particiones tomando secuencias ordenadas de mxima longitud en lugar de secuencias de tamao fijo previamente determinadas. Luego realiza la fusin de las secuencias ordenadas, alternativamente sobre dos archivos aplicando estas acciones en forma repetida se lograra que el archivo original quede ordenado. Para la realizacin de este proceso de ordenacin se necesitaran cuatro archivos. El archivo original F y tres archivos auxiliares a los que se denominaran F1, F2 y F3. De estos archivos, dos sern considerados de entrada y dos de salida; esto, alternativamente, con el objeto de realizar la fusin-particin. El proceso termina cuando en la realizacin de una fusin-particin el segundo archivo quede vaco.

13

UAA Sistemas Electrnicos

Estructura de Datos

Serna

EJEMPLO : Suponga que se desean ordenar las claves del archivo F utilizando el mtodo de mezcla equilibrada. F: 09 75 14 68 29 17 31 25 04 05 13 18 72 46 61 Los pasos que se realizan son los siguientes: PARTICIN INICIAL F2: 09 75 29 25 46 61 F3: 14 68 17 31 04 05 13 18 72 PRIMERA FUSION-PARTICION F: 09 14 68 75 04 05 13 18 25 46 61 72 F1: 17 29 31 SEGUNDA FUSION-PARTICION F2: 09 14 17 29 31 68 75 F3: 04 05 13 18 25 46 61 72 TERCERA FUSION-PARTICION F: 04 05 09 13 14 17 18 25 29 31 46 61 68 72 75 F1: Obsrvese que al realizar la tercera fusin-particin el segundo archivo queda vaci, por lo que se puede afirmar que el archivo ya se encuentra ordenado.

14

UAA Sistemas Electrnicos

Estructura de Datos

Serna

Bibliografa Y. Langsam, M. J. Augenstein, A. Tenenbaum. Data Structures using C and C++. Prentice Hall, Second edition. ISBN 0-13-036997-7. http://en.wikipedia.org/wiki/Sorting_algorithm

15