Sie sind auf Seite 1von 27

Algoritmo de ordenamiento

Quicksort en accin sobre una lista de nmeros aleatorios. Las lneas horizontales son valores pivote.

En computacin y matemticas un algoritmo de ordenamiento es un algoritmo que pone elementos de una lista o un vector en una secuencia dada por una relacin de orden, es decir, el resultado de salida ha de ser una permutacin o reordenamiento de la entrada que satisfaga la relacin de orden dada. Las relaciones de orden ms usadas son el orden numrico y el orden lexicogrfico. Ordenamientos eficientes son importantes para optimizar el uso de otros algoritmos (como los de bsqueda y fusin) que requieren listas ordenadas para una ejecucin rpida. Tambin es til para poner datos en forma cannica y para generar resultados legibles por humanos. Desde los comienzos de la computacin, el problema del ordenamiento ha atrado gran cantidad de investigacin, tal vez debido a la complejidad de resolverlo eficientemente a pesar de su planteamiento simple y familiar. Por ejemplo, BubbleSort fue analizado desde 1956.1 Aunque muchos puedan considerarlo un problema resuelto, nuevos y tiles algoritmos de ordenamiento se siguen inventado hasta el da de hoy (por ejemplo, elordenamiento de biblioteca se public por primera vez en el 2004). Los algoritmos de ordenamiento son comunes en las clases introductorias a la computacin, donde la abundancia de algoritmos para el problema proporciona una gentil introduccin a la variedad de conceptos ncleo de los algoritmos, como notacin de O mayscula, algoritmos divide y vencers, estructuras de datos, anlisis de los casos peor, mejor, y promedio, y lmites inferiores.
Contenido
[ocultar]

1 Clasificacin 2 Estabilidad 3 Lista de algoritmos de ordenamiento

4 Referencias 5 Enlaces externos

[editar]Clasificacin
Los algoritmos de ordenamiento se pueden clasificar de las siguientes maneras:

La ms comn es clasificar segn el lugar donde se realice la ordenacin

Algoritmos de ordenamiento interno: en la memoria del ordenador. Algoritmos de ordenamiento externo: en un lugar externo como un disco duro.

Por el tiempo que tardan en realizar la ordenacin, dadas entradas ya ordenadas o inversamente ordenadas:

Algoritmos de ordenacin natural: Tarda lo mnimo posible cuando la entrada est ordenada. Algoritmos de ordenacin no natural: Tarda lo mnimo posible cuando la entrada est inversamente ordenada.

Por estabilidad: un ordenamiento estable mantiene el orden relativo que tenan originalmente los elementos con claves iguales. Por ejemplo, si una lista ordenada por fecha se reordena en orden alfabtico con un algoritmo estable, todos los elementos cuya clave alfabtica sea la misma quedarn en orden de fecha. Otro caso sera cuando no interesan las maysculas y minsculas, pero se quiere que si una clave aBC estaba antes que AbC, en el resultado ambas claves aparezcan juntas y en el orden original: aBC, AbC. Cuando los elementos son indistinguibles (porque cada elemento se ordena por la clave completa) la estabilidad no interesa. Los algoritmos de ordenamiento que no son estables se pueden implementar para que s lo sean. Una manera de hacer esto es modificar artificialmente la clave de ordenamiento de modo que la posicin original en la lista participe del ordenamiento en caso de coincidencia.

Los algoritmos se distinguen por las siguientes caractersticas:

Complejidad computacional (peor caso, caso promedio y mejor caso) en trminos de n, el tamao de la lista o arreglo. Para esto se usa el concepto de orden de una funcin y se usa la notacinO(n). El mejor comportamiento para ordenar (si no se aprovecha la estructura de las claves) es O(n log n). Los algoritmos ms simples son cuadrticos, es decir O(n). Los algoritmos que aprovechan la estructura de las claves de ordenamiento (p. ej. bucket sort) pueden ordenar en O(kn) donde k es el tamao del espacio de claves. Como dicho tamao es conocido a priori, se puede decir que estos algoritmos tienen un desempeo lineal, es decir O(n).

Uso de memoria y otros recursos computacionales. Tambin se usa la notacin O(n).

[editar]Estabilidad
Los algoritmos de ordenamiento estable mantienen un relativo preorden total. Esto significa que un algoritmo es estable solo cuando hay dos registros R y S con la misma clave y con R apareciendo antes que S en la lista original. Cuando elementos iguales (indistinguibles entre s), como nmeros enteros, o ms generalmente, cualquier tipo de dato en donde el elemento entero es la clave, la estabilidad no es un problema. De todas formas, se asume que los siguientes pares de nmeros estn por ser ordenados por su primer componente:

(4, 1)

(3, 7)

(3, 1)

(5, 6)

En este caso, dos resultados diferentes son posibles, uno de los cuales mantiene un orden relativo de registros con claves iguales, y una en la que no:

(3, 7) (3, 1)

(3, 1) (3, 7)

(4, 1) (4, 1)

(5, 6) (5, 6)

(orden mantenido) (orden cambiado)

Los algoritmos de ordenamiento inestable pueden cambiar el orden relativo de registros con claves iguales, pero los algoritmos estables nunca lo hacen. Los algoritmos inestables pueden ser implementados especialmente para ser estables. Una forma de hacerlo es extender artificialmente el cotejamiento de claves, para que las comparaciones entre dos objetos con claves iguales sean decididas usando el orden de las entradas original. Recordar este orden entre dos objetos con claves iguales es una solucin poco prctica, ya que generalmente acarrea tener almacenamiento adicional. Ordenar segn una clave primaria, secundaria, terciara, etc., puede ser realizado utilizando cualquier mtodo de ordenamiento, tomando todas las claves en consideracin (en otras palabras, usando una sola clave compuesta). Si un mtodo de ordenamiento es estable, es posible ordenar mltiples tems, cada vez con una clave distinta. En este caso, las claves necesitan estar aplicadas en orden de aumentar la prioridad. Ejemplo: ordenar pares de nmeros, usando ambos valores

(4, 1) (4, 1) valor)

(3, 7) (3, 1)

(3, 1) (4, 6)

(4, 6) (original) (3, 7) (despus de ser ordenado por el segundo

(3, 1) valor)

(3, 7)

(4, 1)

(4, 6) (despus de ser ordenado por el primer

Por otro lado:

(3, 7) valor) (3, 1) valor,

(3, 1) (4, 1)

(4, 1) (4, 6)

(4, 6) (despus de ser ordenado por el primer (3, 7) (despus de ser ordenando por el segundo el orden por el primer valor es

perturbado) [editar]Lista

de algoritmos de ordenamiento

Algunos algoritmos de ordenamiento agrupados segn estabilidad tomando en cuenta la complejidad computacional.
Estables

Nombre traducido

Nombre original

Complejidad

Memoria Mtodo

Ordenamiento de burbuja

Bubblesort

O(n)

O(1)

Intercambio

Ordenamiento de burbuja bidireccional

Cocktail sort

O(n)

O(1)

Intercambio

Ordenamiento por insercin

Insertion sort

O(n)

O(1)

Insercin

Ordenamiento por casilleros

Bucket sort

O(n)

O(n)

No comparativo

Ordenamiento por cuentas

Counting sort

O(n+k)

O(n+k)

No comparativo

Ordenamiento por mezcla

Merge sort

O(n log n)

O(n)

Mezcla

Ordenamiento con rbol binario

Binary tree sort

O(n log n)

O(n)

Insercin

Pigeonhole sort

O(n+k)

O(k)

Ordenamiento Radix

Radix sort

O(nk)

O(n)

No comparativo

Distribution sort

O(n) versin recursiva

O(n)

Gnome sort

O(n)

Inestables

Nombre traducido

Nombre original

Complejidad

Memoria Mtodo

Ordenamiento Shell

Shell sort

O(n1.25)

O(1)

Insercin

Comb sort

O(n log n)

O(1)

Intercambio

Ordenamiento por seleccin

Selection sort

O(n)

O(1)

Seleccin

Ordenamiento por montculos

Heapsort

O(n log n)

O(1)

Seleccin

Smoothsort

O(n log n)

O(1)

Seleccin

Ordenamiento rpido

Quicksort

Promedio: O(n log n), peor caso: O(n)

O(log n) Particin

Several Unique Sort

Promedio: O(n u), peor caso: O(n); u=n; u = nmero nico de registros

Cuestionables, imprcticos

Nombre traducido

Nombre original

Complejidad

Memoria Mtodo

Bogosort

O(n n!), peor: no termina

Pancake sorting

O(n), excepto en mquinas de Von Neumann

Randomsort

[editar]Referencias
1. Bubble Sort: An archaeological algorithm analysis. Owen Astrachan

[editar]Enlaces

externos

Explicacin de los distintos mtodos de ordenamiento en Java. (pdf) Discusin sobre varios algoritmos de ordenacin y sus caractersticas (licencia GFDL) (pdf) Animacin de algoritmos de ordenamiento Animacin de algoritmos de ordenamiento (en ingls) ALT: Algorithm Learning Tool. Herramienta de apoyo a la enseanza de algoritmos que muestra grficamente su funcionamiento. Permite implementar algoritmos propios y realizar una ejecucin dinmica e interactiva

Cdigos de Ordenamiento en Python

Algoritmos de Ordenamiento
Debido a que las estructuras de datos son utilizadas para almacenar informacin, para poder recuperar esa informacin de manera eficiente es deseable que aquella est ordenada. Existen varios mtodos para ordenar las diferentes estructuras de datos bsicas. En general los mtodos de ordenamiento no son utilizados con frecuencia, en algunos casos slo una vez. Hay mtodos muy simples de implementar que son tiles en los casos en dnde el nmero de elementos a ordenar no es muy grande (ej, menos de 500 elementos). Por otro lado hay mtodos sofisticados, ms difciles de implementar pero que son ms eficientes en cuestin de tiempo de ejecucin. Los mtodos sencillos por lo general requieren de aproximadamente n x n pasos para ordenar n elementos. Los mtodos simples son: insertion sort (o por insercin directa) selection sort, bubble sort, y shellsort, en dnde el ltimo es una extensn al insertion sort, siendo ms rpido. Los mtodos ms complejos son el quick-sort, el heap sort, radix y address-calculation sort. El ordenar un grupo de datos significa mover los datos o sus referencias para que queden en una secuencia tal que represente un orden, el cual puede ser numrico, alfabtico o incluso alfanumrico, ascendente o descendente. Se ha dicho que el ordenamiento puede efectuarse moviendo los registros con las claves. El mover un registo completo implica un costo, el cual se incrementa conforme sea mayor el tamao del registro. Es por ello que es deseable evitar al mximo el movimiento de los registros. Una alternativa es el crear una tabla de referencias a los registros y mover las referencias y no los datos. A continuacin se mostrarn los mtodos de ordenamiento empezando por el ms sencillo y avanzando hacia los mas sofisticados La eficiencia de los algoritmos se mide por el nmero de comparaciones e intercambios que tienen que hacer, es decir, se toma n como el nmero de elementos que tiene el arreglo a ordenar y se dice que un algoritmo realiza O(n2) comparaciones cuando compara n veces los n elementos, n x n = n2. Anlisis de Algoritmos Notacin de Orden Una funcin f(n) se define de orden O(g(n)), es decir, f(n) = O(g(n)) si existen constantes positivas n0 y c tales que: | f(n) | = c * <= | g(n) | , para toda n > n0

100 n3 => O(n3) 6n2 + 2n + 4 => O(n2) 1024 => O(1) 1+2+3+4+...+n-1+n= n * (n+1)/2 = O(n2) Insertion Sort Este es uno de los mtodos ms sencillos. Consta de tomar uno por uno los elementos de un arreglo y recorrerlo hacia su posicin con respecto a los anteriormente ordenados. As empieza con el segundo elemento y lo ordena con respecto al primero. Luego sigue con el tercero y lo coloca en su posicin ordenada con respecto a los dos anteriores, as sucesivamente hasta recorrer todas las posiciones del arreglo. Este es el algoritmo: Procedimiento Insertion Sort Este procedimiento recibe el arreglo de datos a ordenar a[] y altera las posiciones de sus elementos hasta dejarlos ordenados de menor a mayor. N representa el nmero de elementos que contiene a[].
paso 1: [Para cada pos. del arreglo] paso 2: [Inicializa v y j] paso paso paso paso paso 3: 4: 5: 5: 6: For i <- 2 to N do v <- a[i] j <- i. [Compara v con los anteriores] While a[j-1] > v AND j>1 do [Recorre los datos mayores] Set a[j] <- a[j-1], [Decrementa j] set j <- j-1. [Inserta v en su posicin] Set a[j] <- v. [Fin] End.

Ejemplo: Si el arreglo a ordenar es a = ['a','s','o','r','t','i','n','g','e','x','a','m','p','l','e'], el algoritmo va a recorrer el arreglo de izquierda a derecha. Primero toma el segundo dato 's' y lo asigna a v y i toma el valor de la posicin actual de v. Luego compara esta 's' con lo que hay en la posicin j-1, es decir, con 'a'. Debido a que 's' no es menor que 'a' no sucede nada y avanza i.

Ahora v toma el valor 'o' y lo compara con 's', como es menor recorre a la 's' a la posicin de la 'o'; decrementa j, la cual ahora tiene la posicin en dnde estaba la 's'; compara a 'o' con a[j-1] , es decir, con 'a'. Como no es menor que la 'a' sale del for y pone la 'o' en la posicin a[j]. El resultado hasta este punto es el arreglo siguiente: a = ['a','o','s','r',....] As se contina y el resultado final es el arreglo ordenado : a = ['a','a','e','e','g','i','l','m','n','o','p','r','s','t','x']

Selection Sort El mtodo de ordenamiento por seleccin consiste en encontrar el menor de todos los elementos del arreglo e intercambiarlo con el que est en la primera posicin. Luego el segundo mas pequeo, y as sucesivamente hasta ordenar todo el arreglo.

Procedimiento Selection Sort


paso paso paso paso [Para cada pos. del arreglo] [Inicializa la pos. del menor] [Recorre todo el arreglo] [Si a[j] es menor] If a[j] < a[menor] then paso 5: [Reasigna el apuntador al menor] j paso 6: [Intercambia los datos de la pos. min y posicin i] Swap(a, min, j). paso 7: [Fin] End. 1: 2: 3: 4: For i <- 1 to N do menor <- i For j <- i+1 to N do min =

Ejemplo: El arreglo a ordenar es a = ['a','s','o','r','t','i','n','g','e','x','a','m','p','l','e']. Se empieza por recorrer el arreglo hasta encontrar el menor elemento. En este caso el menor elemento es la primera 'a'. De manera que no ocurre ningn cambio. Luego se procede a buscar el siguiente elemento y se encuentra la segunda 'a'. Esta se intercambia con el dato que est en la segunta posicin, la 's', quedando el arreglo as despus de dos recorridos: a = ['a','a','o','r','t','i','n','g','e','x','s','m','p','l','e'].

El siguiente elemento, el tercero en orden de menor mayor es la primera 'e', la cual se intercambia con lo que est en la tercera posicin, o sea, la 'o'. Le sigue la segunda 's', la cual es intercambiada con la 'r'. El arreglo ahora se ve de la siguiente manera: a = ['a','a','e','e','t','i','n','g','o','x','s','m','p','l','r']. De esta manera se va buscando el elemento que debe ir en la siguiente posicin hasta ordenar todo el arreglo. El nmero de comparaciones que realiza este algoritmo es : para el primer elemento se comparan n-1 datos, en general para el elemento isimo se hacen n-i comparaciones, por lo tanto, el total de comparaciones es: la sumatoria para i de 1 a n-1 (n-i) = 1/2 n (n-1).

Shellsort Denominado as por su desarrollador Donald Shell (1959), ordena una estructura de una manera similar a la del Bubble Sort, sin embargo no ordena elementos adyacentes sino que utiliza una segmentacin entre los datos. Esta segmentacin puede ser de cualquier tamao de acuerdo a una secuencia de valores que empiezan con un valor grande (pero menor al tamao total de la estructura) y van disminuyendo hasta llegar al '1'. Una secuencia que se ha comprobado ser de las mejores es: ...1093, 364, 121, 40, 13, 4, 1. En contraste, una secuencia que es mala porque no produce un ordenamiento muy eficiente es ...64, 32, 16, 8, 4, 2, 1. Su complejidad es de O(n1.2) en el mejor caso y de O(n1.25) en el caso promedio.

void shellsort ( int a[], int n) /* Este procedimiento recibe un arreglo a ordenar a[] y el tamao del arreglo n. Utiliza en este caso una serie de t=6 incrementos h=[1,4,13,40,121,364] para el proceso (asumimos que el arreglo no es muy grande). */ { int x,i,j,inc,s; for(s=1; s < t; s++) /* recorre el arreglo de incrementos */ { inc = h[s]; for(i=inc+1; i < n; i++) {

x = a[i]; j = i-inc; while( j > 0 && a[j] > x) { a[j+h] = a[j]; j = j-h; } a[j+h] = x; } } }

Bubble Sort El bubble sort, tambin conocido como ordenamiento burbuja, funciona de la siguiente manera: Se recorre el arreglo intercambiando los elementos adjacentes que estn desordenados. Se recorre el arreglo tantas veces hasta que ya no haya cambios. Prcticamente lo que hace es tomar el elemento mayor y lo va recorriendo de posicin en posicin hasta ponerlo en su lugar. Procedimiento Bubble Sort
paso 1: [Inicializa i al final de arreglo] do paso 2: [Inicia desde la segunda pos.] do paso 4: [Si a[j-1] es mayor que el que le sigue] a[j] then paso 5: [Los intercambia] Swap(a, j-1, j). paso 7: [Fin] End. For i <- N downto 1 For j <- 2 to i If a[j-1] <

Tiempo de ejecucin del bubble sort:


para el mejor caso (un paso) O(n) peor caso n(n-1)/2 promedio O(n2)

Merge Sort El mtodo Quicksort divide la estructura en dos y ordena cada mitad recursivamente. El caso del MergeSort es el opuesto, es decir, en ste mtodo de unen dos estructuras ordenadas para formar una sola ordenada correctamente. Tiene la ventaja de que utiliza un tiempo proporcional a: n log (n), su desventaja radica en que se requiere de un espacio extra para el procedimiento. Este tipo de ordenamiento es til cuando se tiene una estructura ordenada y los nuevos datos a aadir se almacenan en una estructura temporal para despus agregarlos a la estructura original de manera que vuelva a quedar ordenada. Procedimiento MergeSort /*recibe el arreglo a ordenar un ndice l que indica el lmite inferior del arreglo a ordenar y un ndice r que indica el lmite superior*/
void mergesort(int a[], int l, int r) { int i,j,k,m,b[MAX]; if (r > l) { m = (r+l) /2; mergesort(a, l, m); mergesort(a, m+1, r); for (i= m+1; i > l;i--) b[i-1] = a[i-1]; for (j= m; j < r;j++) b[r+m-j] = a[j+1]; for (k=l ; k <=r; k++) if(b[i] < b[j]) a[k] = b[i++]; else a[k] = b[j--]; } } a = {a,s,o,r,t,i,n,g,e,x,a,m,p,l,e} {a,s, o,r, a,o,r,s, i,t, g,n, g,i,n,t, a,g,i,n,o,r,s,t, e,x, a,m, a,e,m,x, l,p, e,l,p}

a,e,e,l,m,p,x} a = {a,a,e,e,g,i,l,m,n,o,p,r,s,t,x}

Heap Sort
Este mtodo garantiza que el tiempo de ejecucin siempre es de: O(n log n) El significado de heap en ciencia computacional 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. (Nota: se utiliza un arreglo que inicia en la posicin 1 y no en cero, de tal manera que al implementarla en C se tienen n+1 posiciones en el arreglo.) 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 Sort consiste ecencialmente 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.

Procedimiento Heapsort /* Recibe como parmetros un arreglo a ordenar y un entero que indica el numero de datros a ordenar */
void heapsort(int a[], int N) { int k; for(k=N/2; k>=1; k--) downheap(a,N,k); while(N > 1) { swap(a,1,N); downheap(a,--N,1); }

} /* el procedimiento downheap ordena el &aacure;rbol de heap para que el nodo padre sea mayor que sus hijos */ void downheap(int a[], int N, int r) { int j, v; v = a[r]; while (r <= N/2) { j = 2*r; if(j < N && a[j] < a[j+1]); j++; if( v >= a[j]) break; a[r] = a[j]; r = j; } a[r] = v; }

Partition-Exchange Sort o Quicksort Es un mtodo de ordenamiento recursivo y en lenguajes en dnde no se permite la recursividad esto puede causar un retraso significativo en la ejecucin del quicksort. Su tiempo de ejecucin es de n log2n en promedio.
void quicksort(int a[], int l, int r) { int i,j,v; if(r > l) { v = a[r]; i = l-1; j = r; for(;;) { while(a[++i] < v && i < r); while(a[--j] > v && j > l); if( i >= j) break; swap(a,i,j); }

swap(a,i,r); quicksort(a,l,i-1); quicksort(a,i+1,r); } }

a = {a,s,o,r,t,i,n} aiortsn ainrtso ainotsr ainorst

Ordenamiento de raz (radix sort).


Este ordenamiento se basa en los valores de los dgitos reales en las representaciones de posiciones de los nmeros que se ordenan. Por ejemplo el nmero 235 se escribe 2 en la posicin de centenas, un 3 en la posicin de decenas y un 5 en la posicin de unidades. Reglas para ordenar.

Empezar en el dgito ms significativo y avanzar por los dgitos menos significativos mientras coinciden los dgitos correspondientes en los dos nmeros. El nmero con el dgito ms grande en la primera posicin en la cual los dgitos de los dos nmeros no coinciden es el mayor de los dos (por supuesto s coinciden todos los dgitos de ambos nmeros, son iguales).

Este mismo principio se toma para Radix Sort, para visualizar esto mejor tenemos el siguiente ejemplo. En el ejemplo anterior se ordeno de izquierda a derecha. Ahora vamos a ordenar de derecha a izquierda. Archivo original. 25 57 48 37 12 92 86 33

Asignamos colas basadas en el dgito menos significativo. Parte delantera Parte posterior 0 1 212 92
333

4 525 686 757 37 848 9 10 Despus de la primera pasada: 12 92 33 25 86 57 37 48 Colas basadas en el dgito ms significativo.

Parte delantera Parte posterior 0 112 225 333 37 448 557 6 7 886 992 10

Archivo ordenado: 12 25 33 37 48 57 86 92

ASORTINGEXAMPLE AEOLMINGEAXTPRS AEAEGINMLO AAEEG AA AA EEG EE INMLO LMNO LM NO STPRX SRPT PRS RS
#include #include #define NUMELTS 20 void radixsort(int x[], int n) { int front[10], rear[10]; struct { int info; int next;

} node[NUMELTS]; int exp, first, i, j, k, p, q, y; /* Inicializar una lista viculada */ for (i = 0; i < n-1; i++) { node[i].info = x[i]; node[i].next = i+1; } /* fin del for */ node[n-1].info = x[n-1]; node[n-1].next = -1; first = 0; /*first es la cabeza de la lista vinculada */ for (k = 1; k < 5; k++) { /* Suponer que tenemos nmeros de cuatro dgitos */ for (i = 0; i < 10; i++) { /*Inicializar colas */ rear[i] = -1; front[i] = -1; } /*fin del for */ /* Procesar cada elemento en la lista */ while (first != -1) { p = first; first = node[first].next; y = node[p].info; /* Extraer el ksimo dgito */ exp = pow(10, k-1); /* elevar 10 a la (k-1)sima potencia */ j = (y/exp) % 10; /* Insertar y en queue[j] */ q = rear[j]; if (q == -1) front[j] = p; else node[q].next = p; rear[j] = p; } /*fin del while */ /* En este punto, cada registro est en su cola bas ndose en el dgito k Ahora formar una lista nica de todos los elementos de la cola. Encontrar el primer elemento. */ for (j = 0; j < 10 && front[j] == -1; j++); ; first = front[j]; /* Vincular las colas restantes */ while (j <= 9) { /*Verificar si se ha terminado */ /*Encontrar el elemento siguiente */ for (i = j+1; i < 10 && front[i] == -1; i++); ; if (i <= 9) { p = i; node[rear[j]].next = front[i]; } /* fin del if */ j = i; } /* fin del while */ node[rear[p]].next = -1; } /* fin del for */

/* Copiar de regreso al archivo original */ for (i = 0; i < n; i++) { x[i] = node[first].info; first = node[first].next; } /*fin del for */ } /* fin de radixsort*/ int main(void) { int x[50] = {NULL}, i; static int n; printf("\nCadena de nmeros enteros: \n"); for (n = 0;; n++) if (!scanf("%d", &x[n])) break; if (n) radixsort (x, n); for (i = 0; i < n; i++) printf("%d ", x[i]); return 0; }

Estado de la lista

Node[i].info Node[i].next Inicializacin K = 1 K = 2 K = 3

0 1 2 3

65 789 123 457

1 2 3 -1

3 -1 0 1

1 -1 3 0

2 -1 3 1

rear = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1} 2031 front = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1} 2031

k=1 p=0p=1p=2p=3 first = 1 first = 2 first = 3 first = -1 y = 65 y = 789 y = 123 y = 457 exp = 1 exp = 1 exp = 1 exp = 1 j=5j=9j=3j=7 q = -1 q = -1 q = -1 q = -1 si q == -1 si q == -1 si q == -1 si q == -1 front[5] = 0 front[9] = 1 front[3] = 2 front[7] = 3 rear[5] = 0 rear[9] = 1 rear[3] = 2 rear[7] = 3
j = 3 first = 2 while ( j <= 9) i = 5 si i <= 9 p = 5 node[2].next = 0 j = 5 i = 7 si i <= 9 p = 7 node[0].next = 3 j = 5 i = 9 si i <= 9 p = 9 node[2].next = 1 j = 9 fin del while p = 9 node[1].next = -1

Caractersticas.

Debido a que el ciclo for (k = 1; k <= m; k++) externo se recorre m veces (una para cada dgito) y el ciclo interior n veces (una para cada elemento en el archivo) el ordenamiento es de aproximadamente (m*n). Si las llaves son complejas (es decir, si casi cada nmero que puede ser una llave lo es en realidad) m se aproxima a log n, por lo que (m*n) se aproxima a (n logn). Si la cantidad de dgitos es grande, en ocasiones es ms eficiente ordenar el archivo aplicando primero el ordenamiento de raz a los dgitos ms significativos y despus utilizando insercin directa sobre el archivo ordenado.

Ventajas.

El ordenamiento es razonablemente eficiente si el nmero de dgitos en las llaves no es demasiado grande. Si las mquinas tienen la ventaja de ordenar los dgitos (sobre todo si estn en binario) lo ejecutaran con mucho mayor rapidez de lo que ejecutan una comparacin de dos llaves completas.

O rdenamiento por clculo de direccin.


En este mtodo, se aplica una funcin f a cada llave. El res ultado de esta funcin determina dentro de cul entre varios archivos se va a colocar el registro. La funcin debe tener la propiedad de qie si x<=y,f(x),<=f(y). Esta funcin se denomina preservadora de orden .Por tanto, todos lo registros en un subarchivo tendrn llaves que sean menores que o iguales a las llaves de los registros en otros subarchivos. Un elemento se coloca en un subarchivo en secuencia correcta utilizando cualquier mtodo de ordenam iento; con frecencia se utiliza la insercin simple. Despus de que se han colocado todos los elementos del archivo original en subarchivos se concatenan para producir el resultado ordenado. Por ejemplo, considerem os el archivo de muestra. 25 57 48 37 12 92 86 33 Vamos a crear 10 subarchivos,uno para cada uno de los 10 primeros dgitos posibles. Al principio , cada uno de estos subarchivos est vaco. Se declara un arreglo de apuntadores f[10], en donde f[i] apunta al primer elemento en el archivo cuyo dgito es i. Despus de examinar el primer elemento (25), se coloca en el archiv o encabezado por f[2]. Cada uno de los subarchivos se conserva como una lista ligada ordenada de los elementos de arreglo originales. Despus de procesar cada uno de los elementos en el archivo original, aparecen los subarchivos como se muestra a continuacin.

Algoritmo de ordenamiento. Presentamos una rutina para implementar el ordenamiento de clculo de direccin. La rutina supone un arreglo de nmeros de 2 dgitos y u tiliza el primer dgito de cada nmero para asignar cada nmero a un subarchivo.

#define N...

/* N es el numero de elementos a ordenar*/

addr( int x[],int n) { int f[10],first,i,j,p,y; struct{ int info; int next; } node[N] /* Inicializar la lista ligada disponible */ for(i=0;i<n-1;i++) node[i].next=i+1; node[n-1].ne

xt=-1; for(i=0;i<n;i++) node[i].info=x[i]; /* Inicializar los apuntadores */ for(i=0;i<10;i++) f[i]=-1; for(i=0;i<n;i++) { /* Insertamos sucesivamente cada elemento en su */ /* subarchivo respectivo utilizando inserc in de lista */ y=x[i]; first=y/10; /* Encontrar el dgito de las decenas */ /* Buscar en la lista ligada */ place(&f[first],y); /* place inserta "y" en su posicin correcta en la lis ta */ /* a la que se apunta mediante f[first] */ } /* Copiar los nmeros de regreso al erreglo x */ i=0; for(j=0;j<10;j++) { p=f[j]; while(p!=-1) { x[i++]=node[p].info; p=node[p].next; } } }

Programa de ordemaniento por clculo de direccin.

#include <stdio.h> #include <conio.h> #define N 8 main(void) { int x[N],f[10]; int i,j,p,a,s,y,first;

struct{ int info; int next; }node[N]; clrsc r(); for(i=0;i<N;i++) /*lectura del arreglo x[N] a ordenar*/ { printf("x[%d]=",i); scanf("%d",&x[i]); } for(i=0;i<N-1;i++) node[i].next=i+; tadores*/ node[N-1].next=-1; for(i=0;i<N;i++) node[i].info=x[i]; for(i=0;i<10;i++) f[10]*/ f[i]=-1; na da */ for(i=0;i<N;i++) { y=x[i]; decenas*/ first=y/10; if(f[first]==-1) dato*/ { f[firs t]=i; node[i].next=-1; } else a un dato*/ { if(node[f[first]].next==-1) dato en lista*/ { if(node[f[first]].info < y) { node[f[first]].next=i; node[i].next=-1; } else { node[i].next=f[first]; node[f[first]].next=-1; f[first]=i; } /*apunta al primer /* f[first] apunta /*f[first] no apunta a nign /*clculo del digito de las /*Creacin de sub-listas*/ /*al principio f[i] no apunta a /*Inicio de la lista disponible*/ /*apun

/*dato*/ /*Inicializacin de apuntadores

} else lista*/ { a=f[first]; anterior*/ xt;

/*Se continua la /*a=

s=node[a].ne /*s= siguiente*/ if(y<node[f[first]].info) { f[first]=i; node[i].next=a; } else { while(y>node[s].info&&s!=-1) { a=s; s=node[s].next; } node[a].next=i; /*i semejante a temp*/ node[i].next=s; } } } } i=0; /*Copiar los nmeros de regreso*/ for(j=0;j<10;j++) /* al arreglo x[N] */ { p=f[j]; while(p!=-1) { x[i++]=node[p].info; p=node[p].next; } } printf("\n"); for(i=0;i<N;i++) printf("x[%d]=%d\n",i,x[i]); getchar(); }

Los requisitos de espacio del ordenamiento de calculo de direccin son aproximadamente 2*n (utilizado mediante el arreglo node) ms algunos nodos de encabezado y variables temporales. Observe que si los datos originales se proporcionan en la forma de una

lista ligada y no como un arreglo secuencia l, no es necesario conservar el arreglo x y la estructura vinculada node. Para evaluar los requisitos de tiempo para el ordenamiento considere lo siguiente: si la distribucin aproximada de los n elementos originales est uniform emnete distribuida por los m subarchivos y el valor de n/m es aproximadamente 1, el tiempo de ordenamiento es casi O(n),dado que la funcin asigna cada elemento a su propio archivo y se requiere poco trabajo adicional para colocar el elemento dent ro del subarchivo mismo. Por otra parte, si n/m es mucho ms grande que 1, o si el archivo original no esta uniformemente distribuido por los m subarchivos, se requiere bastante trabajo para insertar un elemento en su propio suba

Das könnte Ihnen auch gefallen