http://www.uv.es/zuniga/09_La_distribucio n_de_Poisson.

pdf

Algoritmos de Ordenamiento
Debido a que las estructuras de datos son utilizadas para almacenar información, para poder recuperar esa información de manera eficiente es deseable que aquella esté ordenada. Existen varios métodos para ordenar las diferentes estructuras de datos básicas. En general los métodos de ordenamiento no son utilizados con frecuencia, en algunos casos sólo una vez. Hay métodos muy simples de implementar que son útiles en los casos en dónde el número de elementos a ordenar no es muy grande (ej, menos de 500 elementos). Por otro lado hay métodos sofisticados, más difíciles de implementar pero que son más eficientes en cuestión de tiempo de ejecución. Los métodos sencillos por lo general requieren de aproximadamente n x n pasos para ordenar n elementos. Los métodos simples son: insertion sort (o por inserción directa) selection sort, bubble sort, y shellsort, en dónde el último es una extensón al insertion sort, siendo más rápido. Los métodos más 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 numérico, alfabético o incluso alfanumérico, 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 tamaño del registro. Es por ello que es deseable evitar al máximo 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 continuación se mostrarán los métodos de ordenamiento empezando por el más sencillo y avanzando hacia los mas sofisticados La eficiencia de los algoritmos se mide por el número de comparaciones e intercambios que tienen que hacer, es decir, se toma n como el número 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. Análisis de Algoritmos Notación de Orden Una función 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)

'o'..] Así se continúa y el resultado final es el arreglo ordenado : . con 'a'. como es menor recorre a la 's' a la posición de la 'o'.'e'].'a'.'r'.v. es decir.+n-1+n= n * (n+1)/2 = O(n2) Insertion Sort Este es uno de los métodos más sencillos. Así empieza con el segundo elemento y lo ordena con respecto al primero. así sucesivamente hasta recorrer todas las posiciones del arreglo.'n'. el algoritmo va a recorrer el arreglo de izquierda a derecha.'m'.'p'. decrementa j. Consta de tomar uno por uno los elementos de un arreglo y recorrerlo hacia su posición con respecto a los anteriormente ordenados. El resultado hasta este punto es el arreglo siguiente: a = ['a'. [Compara v con los anteriores] While a[j-1] > v AND j>1 do [Recorre los datos mayores] Set a[j] <. la cual ahora tiene la posición en dónde estaba la 's'...a[j-1]. Ahora v toma el valor 'o' y lo compara con 's'. con 'a'.'s'. Luego sigue con el tercero y lo coloca en su posición ordenada con respecto a los dos anteriores. paso 1: [Para cada pos. es decir.. [Inserta v en su posición] Set a[j] <.2 to N do v <. Primero toma el segundo dato 's' y lo asigna a v y i toma el valor de la posición actual de v.'t'. Como no es menor que la 'a' sale del for y pone la 'o' en la posición a[j].'g'. [Fin] End. Debido a que 's' no es menor que 'a' no sucede nada y avanza i.'r'.'s'..'o'.a[i] j <. 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.'x'.. compara a 'o' con a[j-1] .j-1. Luego compara esta 's' con lo que hay en la posición j-1.'i'. del arreglo] paso 2: [Inicializa v y j] paso paso paso paso paso 3: 4: 5: 5: 6: For i <.6n2 + 2n + 4 => O(n2) 1024 => O(1) 1+2+3+4+.i. Ejemplo: Si el arreglo a ordenar es a = ['a'.'e'. N representa el número de elementos que contiene a[]. [Decrementa j] set j <.'l'.

's'. Luego se procede a buscar el siguiente elemento y se encuentra la segunda 'a'. 1: 2: 3: 4: For i <.'g'.'l'.'x'] y Selection Sort El método de ordenamiento por selección consiste en encontrar el menor de todos los elementos del arreglo e intercambiarlo con el que está en la primera posición. De manera que no ocurre ningún cambio.'s'. la 's'.'t'. la cual es intercambiada con la 'r'.'o'. El siguiente elemento.'e'. Procedimiento Selection Sort paso paso paso paso [Para cada pos.'r'. la cual se intercambia con lo que está en la tercera posición.'i'. Le sigue la segunda 's'.'o'.'e'].'x'.'n'.'a'.'n'. El arreglo ahora se ve de la siguiente manera: a = ['a'.'l'. del arreglo] [Inicializa la pos. la 'o'.'l'.'e'.'p'. En este caso el menor elemento es la primera 'a'.i For j <.'x'.'t'.'e'].'r'.'o'.a = ['a'.'r']. quedando el arreglo así después de dos recorridos: a = ['a'.'p'.'p'. min.'a'.'i'. 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. El número de comparaciones que realiza este algoritmo es : para el primer elemento se comparan n-1 datos.'l'. o sea. Luego el segundo mas pequeño. min y posición i] Swap(a.'m'.'g'.'i'. j). De esta manera se va buscando el elemento que debe ir en la siguiente posición hasta ordenar todo el arreglo.'e'. Shellsort .'m'. por lo tanto.'n'.i+1 to N do min = Ejemplo: El arreglo a ordenar es a = ['a'. Esta se intercambia con el dato que está en la segunta posición. y así sucesivamente hasta ordenar todo el arreglo.'g'.'s'.'o'. el tercero en orden de menor mayor es la primera 'e'. en general para el elemento i-ésimo se hacen n-i comparaciones. paso 7: [Fin] End.'t'.'p'.'n'.'t'.'a'.'i'. el total de comparaciones es: la sumatoria para i de 1 a n-1 (n-i) = 1/2 n (n-1).'e'.'e'.'m'.'a'. Se empieza por recorrer el arreglo hasta encontrar el menor elemento.'x'.'e'.'g'.1 to N do menor <.'s'.'r'.'m'.

2.121. Procedimiento Bubble Sort . 4. también conocido como ordenamiento burbuja. Una secuencia que se ha comprobado ser de las mejores es: . Esta segmentación puede ser de cualquier tamaño de acuerdo a una secuencia de valores que empiezan con un valor grande (pero menor al tamaño total de la estructura) y van disminuyendo hasta llegar al '1'.40. 13. i < n.Denominado así por su desarrollador Donald Shell (1959). Utiliza en este caso una serie de t=6 incrementos h=[1. ordena una estructura de una manera similar a la del Bubble Sort. for(i=inc+1.j. Su complejidad es de O(n1. s++) /* recorre el arreglo de incrementos */ { inc = h[s]. 32. 121.s. Se recorre el arreglo tantas veces hasta que ya no haya cambios.13.2) en el mejor caso y de O(n1. for(s=1. 364...i. En contraste. j = i-inc.364] para el proceso (asumimos que el arreglo no es muy grande). sin embargo no ordena elementos adyacentes sino que utiliza una segmentación entre los datos. s < t. j = j-h. } a[j+h] = x.inc. 16. } } } Bubble Sort El bubble sort. void shellsort ( int a[]. 1.64. 40.1093. while( j > 0 && a[j] > x) { a[j+h] = a[j].25) en el caso promedio.. 4. funciona de la siguiente manera: Se recorre el arreglo intercambiando los elementos adjacentes que estén desordenados.4. una secuencia que es mala porque no produce un ordenamiento muy eficiente es . Prácticamente lo que hace es tomar el elemento mayor y lo va recorriendo de posición en posición hasta ponerlo en su lugar. */ { int x. 1. 8.. i++) { x = a[i]. int n) /* Este procedimiento recibe un arreglo a ordenar a[] y el tamaño del arreglo n.

for (j= m.2 to i If a[j-1] < Tiempo de ejecución del bubble sort: y y y para el mejor caso (un paso) O(n) peor caso n(n-1)/2 promedio O(n2) Merge Sort El método Quicksort divide la estructura en dos y ordena cada mitad recursivamente. m+1. Este tipo de ordenamiento es útil cuando se tiene una estructura ordenada y los nuevos datos a añadir se almacenan en una estructura temporal para después agregarlos a la estructura original de manera que vuelva a quedar ordenada. int r) { int i. mergesort(a. j-1. l. int l. m). su desventaja radica en que se requiere de un espacio extra para el procedimiento.j.k. Tiene la ventaja de que utiliza un tiempo proporcional a: n log (n). en éste método de unen dos estructuras ordenadas para formar una sola ordenada correctamente.j++) b[r+m-j] = a[j+1].m.] do paso 4: [Si a[j-1] es mayor que el que le sigue] a[j] then paso 5: [Los intercambia] Swap(a. r). El caso del MergeSort es el opuesto. k <=r. i > l. for (i= m+1.N downto 1 For j <. j). Procedimiento MergeSort /*recibe el arreglo a ordenar un índice l que indica el límite inferior del arreglo a ordenar y un índice r que indica el límite superior*/ void mergesort(int a[]. es decir.b[MAX]. if (r > l) { m = (r+l) /2. mergesort(a. k++) if(b[i] < b[j]) a[k] = b[i++]. for (k=l . paso 7: [Fin] End. For i <.i--) b[i-1] = a[i-1]. j < r. .paso 1: [Inicializa i al final de arreglo] do paso 2: [Inicia desde la segunda pos.

m.e} {a.m.) Se mapea un árbol binario de tal manera en el arreglo que el nodo en la posición i es el padre de los nodos en las posiciones (2*i) y (2*i+1).p.x.r. a.e.r.s.t.i.o.g. } } a = {a. a.p.t.i.o.l.m.p.e.o.x.n.n. Tiene las siguientes características: y y y Un heap es un arreglo de n posiciones ocupado por los elementos de la cola.t.i.e. . o.a.p.n.t.x.r. g. Por consiguiente.r.n. el nodo padre tiene el mayor valor de todo su subárbol. e. a. i. de tal manera que al implementarla en C se tienen n+1 posiciones en el arreglo. g.r.l.g.m.l.x} Heap Sort Este método garantiza que el tiempo de ejecución siempre es de: O(n log n) El significado de heap en ciencia computacional es el de una cola de prioridades (priority queue).n. El valor en un nodo es mayor o igual a los valores de sus hijos.s.s. l. Heap Sort consiste ecencialmente en: y y y convertir el arreglo en un heap construir un arreglo ordenado de atrás hacia adelante (mayor a menor) repitiendo los siguientes pasos: o sacar el valor máximo en el heap (el de la posición 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. (Nota: se utiliza un arreglo que inicia en la posición 1 y no en cero.p} a.a.i.x} a = {a.s.l.t.e.e. a.else a[k] = b[j--]. e.o.e.s.g.m.

1). int r) a[r]. } a[r] = v.j. downheap(a. int r) { int j.1. } } /* el procedimiento downheap ordena el &aacure. if(j < N && a[j] < a[j+1]). a[r] = a[j].N. void quicksort(int { int i. .N). l-1. if(r > l) { v = i = j = a[]. if( v >= a[j]) break. int l. r. while(N > 1) { swap(a. for(k=N/2. } Partition-Exchange Sort o Quicksort Es un método de ordenamiento recursivo y en lenguajes en dónde no se permite la recursividad esto puede causar un retraso significativo en la ejecución del quicksort. k--) downheap(a.rbol de heap para que el nodo padre sea mayor que sus hijos */ void downheap(int a[]. while (r <= N/2) { j = 2*r.v. Su tiempo de ejecución es de n log2n en promedio. int N) { int k. r = j.Procedimiento Heapsort /* Recibe como parámetros un arreglo a ordenar y un entero que indica el numero de datros a ordenar */ void heapsort(int a[]. v. int N.k). k>=1. v = a[r].--N. j++.

quicksort(a.i-1). } } . if( i >= j) break.i. while(a[--j] > v && j > l).r). quicksort(a.for(..l.i. } swap(a.r).j).) { while(a[++i] < v && i < r). swap(a.i+1.