Algoritmos y Estructura de Datos Parte 4 de 7: Búsqueda y Clasificación Libros de Wikipedia 2015 Por Wikipedians EDITADO POR: Reiner Creutzburg, Montserrat Rodríguez, Dulce García, María Martínez Fachhochschule Brandenburg Fachbereich Informatik und Medien PF 2132 D-‐14737 Brandenburg , Germany Email: creutzburg@fh-‐brandenburg.de Índice general 1 2 Busqueda 1 1.1 Algoritmo de búsqueda . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1.1.1 Búsqueda secuencial . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1.1.2 Búsqueda dicotómica (binaria) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1.1.3 Enlaces externos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 Clasificacion 3 2.1 Algoritmo de agrupamiento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 2.1.1 Aplicaciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 2.1.2 Algoritmos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 2.1.3 Véase también . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 2.1.4 Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 2.1.5 Enlaces externos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 Quicksort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 2.2.1 Descripción del algoritmo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 2.2.2 Ejemplo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 2.2.3 Véase también . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 2.2.4 Enlaces externos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 Ordenamiento por mezcla . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 2.3.1 Descripción . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 2.3.2 Optimizando merge sort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 2.3.3 Comparación con otros algoritmos de ordenamiento . . . . . . . . . . . . . . . . . . . . . 6 2.3.4 Enlaces externos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 Ordenamiento por inserción . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 2.4.1 Véase también . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 2.4.2 Enlaces externos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 Heapsort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 2.5.1 Descripción . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 2.5.2 Enlaces externos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 2.2 2.3 2.4 2.5 3 Text and image sources, contributors, and licenses 9 3.1 Text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 3.2 Images . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 i Algoritmos y Estructura de Datos Parte 4: Búsqueda y Clasificación Libros de Wikipedia 2015 Por Wikipedians EDITADO POR: Reiner Creutzburg, Montserrat Rodríguez, Dulce García, María Martínez . Fachhochschule Brandenburg Fachbereich Informatik und Medien PF 2132 D-‐14737 Brandenburg Email: creutzburg@fh-‐brandenburg.de Capítulo 1 Busqueda 1.1 Algoritmo de búsqueda 1.1.2 Búsqueda dicotómica (binaria) Se utiliza cuando el vector en el que queremos determinar la existencia de un elemento está previamente ordenado. Este algoritmo reduce el tiempo de búsqueda considerablemente, ya que disminuye exponencialmente el número de iteraciones necesarias. Un algoritmo de búsqueda es aquel que está diseñado para localizar un elemento con ciertas propiedades dentro de una estructura de datos; por ejemplo, ubicar el registro correspondiente a cierta persona en una base de datos, o el mejor movimiento en una partida de ajedrez. Está altamente recomendado para buscar en arrays La variante más simple del problema es la búsqueda de de gran tamaño. Por ejemplo, en uno conteniendo un número en un vector. 50.000.000 elementos, realiza como máximo 26 compaBúsqueda dicotómica raciones (en el peor de los casos). Elementos necesarios en una búsqueda : Para implementar este algoritmo se compara el elemento a buscar con un elemento cualquiera del array (normalmente el elemento central): si el valor de éste es mayor que el del elemento buscado se repite el procedimiento en la parte del array que va desde el inicio de éste hasta el elemento tomado, en caso contrario se toma la parte del array que va desde el elemento tomado hasta el final. De esta manera obtenemos intervalos cada vez más pequeños, hasta que se obtenga un intervalo indivisible. Si el elemento no se encuentra dentro de este último entonces se deduce que el elemento buscado no se encuentra en todo el array. log2 (n) donde n = elementos de la búsqueda Ejemplo: log2 (1.000.000) ≈ 20 1.1.1 Búsqueda secuencial Se utiliza cuando el vector no está ordenado o no puede ser ordenado previamente. Consiste en buscar el elemento comparándolo secuencialmente (de ahí su nombre) con cada elemento del vector hasta encontrarlo, o hasta que se llegue al final. La existencia se puede asegurar cuando el elemento es localizado, pero no podemos asegurar la no existencia hasta no haber analizado todos los elementos del vector. A continuación se muestra el pseudocódigo del algoritmo:[cita requerida] A continuación se presenta el pseudocódigo del algoritmo, tomando como elemento inicial el elemento central del array. Datos de entrada: vec: vector en el que se desea buscar el dato tam: tamaño del vector. Los subíndices válidos van desde 0 hasta tam-1 inclusive. dato: elemento que se quiere buscar. Variables centro: subíndice central del intervalo inf: límite inferior del intervalo sup: límite superior del intervalo inf = 0 sup = tam-1 Mientras inf <= sup: centro = ((sup - inf) / 2) + inf // División entera: se trunca la fracción Si vec[centro] == dato devolver verdadero y/o pos, de lo contrario: Si dato < vec[centro] entonces: sup = centro - 1 En caso contrario: inf = centro + 1 Fin (Mientras) Devolver Falso Datos de entrada: vec: vector en el que se desea buscar el dato tam: tamaño del vector. Los subíndices válidos van desde 0 hasta tam-1 inclusive. Puede representarse así: vec[0...tam) ó vec[0...tam-1]. dato: elemento que se quiere buscar. Variables pos: posición actual en el vector pos = 0 while pos < tam: if vec[pos] == dato: Retorne verdadero y/o pos, else: pos = pos + 1 Fin (while) Retorne falso, • C • C int busquedaSimple(int vector[n], int n, int dato) { int i; for(i=0; i<n; i++){ if(dato==vector[i]) { return i; break; int busquedaBinaria(int vector[], int n, int dato) } } return −1; } { int centro,inf=0,sup=n-1; while(inf<=sup){ centro=(sup+inf)/2; if(vector[centro]==dato) return centro; 1 2 CAPÍTULO 1. BUSQUEDA else if(dato < vector[centro]) sup=centro-1; else 1.1.3 Enlaces externos inf=centro+1; } return −1; } • ALT: Algorithm Learning Tool. Herramienta de apoyo a la enseñanza de algoritmos que muestra gráImplementación recursiva en C++ [cita requerida] ficamente su funcionamiento. Permite implementar algoritmos propios y realizar una ejecución dinámi• C++ ca e interactiva #include <iostream> #include <vector> bool busqueda_dicotomica(const vector<int> &v, int principio, int fin, int &x){ bool res; if(principio <= fin){ int m = (principio + fin)/2; if(x < v[m]) res = busqueda_dicotomica(v, principio, m-1, x); else if(x > v[m]) res = busqueda_dicotomica(v, m+1, fin, x); else res = true; }else res = false; return res; } /*{Post: Si se encuentra devuelve true, sino false}*/ Implementación recursiva en Python • Python def busquedaBinaria (numeros, inicio, fin, elemento): if (inicio == fin): return numeros [inicio] == elemento centro = (inicio + fin) // 2 if (elemento < numeros [centro]): return busquedaBinaria (numeros, inicio, centro, elemento) elif (elemento > numeros [centro]): return busquedaBinaria (numeros, centro + 1, fin, elemento) else: return True def busqueda (numeros, elemento): if (numeros == None) or (numeros == []): return False else: return busquedaBinaria (numeros, 0, len (numeros) - 1, elemento) Implementación recursiva en Python3 • Python def bin(a,x,low,hi): ans = −1 if low==hi: ans = −1 else: mid = (low+((hi-low)//2)) if x < a[mid]: ans = bin(a,x,low,mid) elif x > a[mid]: ans = bin(a,x,mid+1,hi) else: ans = mid return ans # Así se hace el llamado: print(binseacrh(Lista,a_buscar,0,len(Lista))) # Retorna el indice que coincide con 'numero a buscar', sino está retorna −1 # Tiempo: (log n) Implementación iterativa en Python3 • Python def bin(a, c): ans = −1 if a[0] >= c: ans = −1 else: low, hi = 0, len(a) while low+1 != hi: mid = low + ((hi-low)//2) if a[mid] < c: low = mid else: hi = mid ans = low return ans # Así se hace el llamado: print(bin(lista(), numero_a_buscar) ) # Retorna el indice que coincide con 'numero a buscar', sino está retorna −1 # Tiempo: (log n) Capítulo 2 Clasificacion 2.1 Algoritmo de agrupamiento 2.1.2 Algoritmos Un algoritmo de agrupamiento (en inglés, clusteri- Existen dos grandes técnicas para el agrupamiento de cang) es un procedimiento de agrupación de una serie de sos: vectores de acuerdo con un criterio. Esos criterios son por lo general distancia o similitud. La cercanía se defi• Agrupamiento jerárquico, que puede ser aglomerane en términos de una determinada función de distancia, tivo o divisivo. como la euclídea, aunque existen otras más robustas o • Agrupamiento no jerárquico, en los que el númeque permiten extenderla a variables discretas. La mediro de grupos se determina de antemano y las obserda más utilizada para medir la similitud entre los casos vaciones se van asignando a los grupos en función es las matriz de correlación entre los nxn casos. Sin emde su cercanía. Existen los métodos de k-mean y kbargo, también existen muchos algoritmos que se basan medioid. en la máximización de una propiedad estadística llamada verosimilitud. Generalmente, los vectores de un mismo grupo (o clús- Existen diversas implementaciones de algoritmos concreters) comparten propiedades comunes. El conocimiento tos. Por ejemplo, el de las k-medias, de particionamiento. de los grupos puede permitir una descripción sintética de Es uno de los más antiguos pero uso extendido a pesar de un conjunto de datos multidimensional complejo. De ahí sus carencias y falta de robustez. su uso en minería de datos. Esta descripción sintética se El paquete clúster de R-lenguaje [1] implementa una serie consigue sustituyendo la descripción de todos los elemen- de algoritmos de particionamiento como agnes, mona y tos de un grupo por la de un representante característico diana, jerárquicos, y pam, clara y fanny, de particionadel mismo. miento. En algunos contextos, como el de la minería de datos, se lo considera una técnica de aprendizaje no supervisado puesto que busca encontrar relaciones entre variables 2.1.3 Véase también descriptivas pero no la que guardan con respecto a una • Inteligencia de enjambre variable objetivo. 2.1.1 2.1.4 Referencias Aplicaciones [1] Rousseeuw, P.J.; Kaufman, L. (1990). Finding Groups in Data: An Introduction to Clúster Analysis. Wiley. Las técnicas de agrupamiento encuentran aplicación en diversos ámbitos. • En biología para clasificar animales y plantas. 2.1.5 Enlaces externos • En medicina para identificar enfermedades. • • En marketing para identificar personas con hábitos de compras similares. • En teoría de la señal pueden servir para eliminar ruidos. Wikimedia Commons alberga contenido multimedia sobre Algoritmo de agrupamientoCommons. • Implementación Real en C del algoritmo EM para Clustering con Gaussian Mixture Models (GMMs). • En biometría para identificación del locutor o de caras. • Recuperación de Información 3 4 CAPÍTULO 2. CLASIFICACION 2.2 Quicksort • 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 implementación del algoritmo, aunque habitualmente ocurre en listas que se encuentran ordenadas, o casi ordenadas. Pero principalmente depende del pivote, si por ejemplo el algoritmo implementado toma como pivote siempre el primer elemento del array, y el array que le pasamos está ordenado, siempre va a generar a su izquierda un array vacío, lo que es ineficiente. • En el caso promedio, el orden es O(n·log n). No es extraño, pues, que la mayoría de optimizaciones que se aplican al algoritmo se centren en la elección del pivote. Quicksort en acción sobre una lista de números aleatorios. Las líneas horizontales son valores pivote. El ordenamiento rápido (quicksort en inglés) es un algoritmo creado por el científico británico en computación C. A. R. Hoare, basado en la técnica de divide y vencerás, que permite, en promedio, ordenar n elementos en un tiempo proporcional a n log n. Demostración de un caso particular Supongamos que el número de elementos a ordenar es una potencia de dos, es decir, n = 2k para algún natural k . Inmediatamente k = log2 (n) , donde k es el número de divisiones que realizará el algoritmo. En la primera fase del algoritmo habrá n comparaciones. En la segunda fase el algoritmo instanciará dos sublis2.2.1 Descripción del algoritmo tas de tamaño aproximadamente n/2. El número total de comparaciones de estas dos sublistas es: 2(n/2) = n. En El algoritmo trabaja de la siguiente forma: la tercera fase el algoritmo procesará 4 sublistas más, por tanto el número total de comparaciones en esta fase es • Elegir un elemento de la lista de elementos a orde- 4(n/4) = n. nar, al que llamaremos pivote. En conclusión, el número total de comparaciones que ha• Resituar los demás elementos de la lista a cada lado ce el algoritmo es: del pivote, de manera que a un lado queden todos los n + n + n + ..... + n = kn , donde k = log (n) , por 2 menores que él, y al otro los mayores. Los elemen- tanto el Orden de Complejidad del algoritmo en el peor tos iguales al pivote pueden ser colocados tanto a su caso es O(n.log n) . 2 derecha como a su izquierda, dependiendo de la implementación deseada. En este momento, el pivote ocupa exactamente el lugar que le corresponderá en Técnicas de elección del pivote la lista ordenada. El algoritmo básico del método Quicksort consiste en to• La lista queda separada en dos sublistas, una forma- mar cualquier elemento de la lista al cual denominaremos da por los elementos a la izquierda del pivote, y otra como pivote, dependiendo de la partición en que se elija, por los elementos a su derecha. el algoritmo será más o menos eficiente. • Repetir este proceso de forma recursiva para cada sublista mientras éstas contengan más de un elemento. Una vez terminado este proceso todos los elementos estarán ordenados. Como se puede suponer, la eficiencia del algoritmo depende de la posición en la que termine el pivote elegido. • Tomar un elemento cualquiera como pivote tiene la ventaja de no requerir ningún cálculo adicional, lo cual lo hace bastante rápido. Sin embargo, esta elección «a ciegas» siempre provoca que el algoritmo tenga un orden de O(n²) para ciertas permutaciones de los elementos en la lista. • En el mejor caso, el pivote termina en el centro de la lista, dividiéndola en dos sublistas de igual tamaño. En este caso, el orden de complejidad del algoritmo es O(n·log n). • Otra opción puede ser recorrer la lista para saber de antemano qué elemento ocupará la posición central de la lista, para elegirlo como pivote. Esto puede hacerse en O(n) y asegura que hasta en el peor de los casos, el algoritmo sea O(n·log n). No obstante, el 2.2. QUICKSORT cálculo adicional rebaja bastante la eficiencia del algoritmo en el caso promedio. • La opción a medio camino es tomar tres elementos de la lista - por ejemplo, el primero, el segundo, y el último - y compararlos, eligiendo el valor del medio como pivote. 5 • Pese a que en secuencias largas de elementos la probabilidad de hallarse con una configuración de elementos “crítica” es muy baja, esto no evita que sigan apareciendo (a veces, de manera intencionada). El algoritmo introsort es una extensión del algoritmo quicksort que resuelve este problema utilizando heapsort en vez de quicksort cuando el número de recursiones excede al esperado. Técnicas de reposicionamiento Nota: Los tres parámetros de la llamada inicial a Quicksort serán array[0], 0, numero_elementos −1, es decir, si Una idea preliminar para ubicar el pivote en su posición es un array de 6 elementos array, 0, 5 final sería contar la cantidad de elementos menores que él, y colocarlo un lugar más arriba, moviendo luego todos esos elementos menores que él a su izquierda, para que 2.2.2 Ejemplo pueda aplicarse la recursividad. Existe, no obstante, un procedimiento mucho más efec- En el siguiente ejemplo se marcan el pivote y los índices tivo. Se utilizan dos índices: i, al que llamaremos índice i y j con las letras p, i y j respectivamente. izquierdo, y j, al que llamaremos índice derecho. El al- Comenzamos con la lista completa. El elemento pivote goritmo es el siguiente: será el 4: 5-3-7-6-2-1-4p • Recorrer la lista simultáneamente con i y j: por la izquierda con i (desde el primer elemento), y por la derecha con j (desde el último elemento). Comparamos con el 5 por la izquierda y el 1 por la derecha. 5-3-7-6-2-1-4ijp • Cuando lista[i] sea mayor que el pivote y lista[j] sea 5 es mayor que 4 y 1 es menor. Intercambiamos: menor, se intercambian los elementos en esas posi1-3-7-6-2-5-4ijp ciones. Avanzamos por la izquierda y la derecha: • Repetir esto hasta que se crucen los índices. 1-3-7-6-2-5-4ijp • El punto en que se cruzan los índices es la posición 3 es menor que 4: avanzamos por la izquierda. 2 es menor adecuada para colocar el pivote, porque sabemos que 4: nos mantenemos ahí. que a un lado los elementos son todos menores y al otro son todos mayores (o habrían sido intercam- 1 - 3 - 7 - 6 - 2 - 5 - 4 i j p biados). 7 es mayor que 4 y 2 es menor: intercambiamos. 1-3-2-6-7-5-4ijp Transición a otro algoritmo Como se mencionó anteriormente, el algoritmo quicksort ofrece un orden de ejecución O(n²) para ciertas permutaciones “críticas” de los elementos de la lista, que siempre surgen cuando se elige el pivote «a ciegas». La permutación concreta depende del pivote elegido, pero suele corresponder a secuencias ordenadas. Se tiene que la probabilidad de encontrarse con una de estas secuencias es inversamente proporcional a su tamaño. 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] (pasos 16-18): 1-3-2-4-7-5-6p Aplicamos recursivamente a la sublista de la izquierda (índices 0 - 2). Tenemos lo siguiente: 1-3-2 • Los últimos pases de quicksort son numerosos y ordenan cantidades pequeña de elementos. Un porcentaje medianamente alto de ellos estarán dispuestos de una manera similar al peor caso del algoritmo, volviendo a éste ineficiente. Una solución a este problema consiste en ordenar las secuencias pequeñas usando otro algoritmo. Habitualmente se aplica el algoritmo de inserción para secuencias de tamaño menores de 8-15 elementos. 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 sublista. Al finalizar y unir todas las sublistas queda la lista inicial ordenada en forma ascendente. 6 CAPÍTULO 2. CLASIFICACION 1-2-3-4-5-6-7 1. Una lista pequeña necesitará menos pasos para ordenarse que una lista grande. 2.2.3 2. Se necesitan menos pasos para construir una lista ordenada a partir de dos listas también ordenadas, que a partir de dos listas desordenadas. Por ejemplo, sólo será necesario entrelazar cada lista una vez que están ordenadas. Véase también • Algoritmo de ordenamiento 2.2.4 Enlaces externos A continuación se describe el algoritmo en pseudocódigo • Distintas implementaciones del algoritmo en Wiki(se advierte de que no se incluyen casos especiales para books (inglés) vectores vacíos, etc.; una implementación en un lenguaje • Distintas implementaciones del algoritmo en Roset- de programación real debería tener en cuenta estos detalles): taCode.org (inglés) function mergesort(m) var list left, right, result if length(m) ≤ 1 return m else var middle = length(m) / 2 for each x in m up to middle - 1 add x to left for each x in m at 2.3 Ordenamiento por mezcla and after middle add x to right left = mergesort(left) right El algoritmo de ordenamiento por mezcla (merge sort en = mergesort(right) if last(left) ≤ first(right) append right inglés) es un algoritmo de ordenamiento externo estable to left return left result = merge(left, right) return result basado en la técnica divide y vencerás. Es de complejidad function merge(left,right) var list result while length(left) > 0 and length(right) > 0 if first(left) ≤ first(right) append O(n log n). first(left) to result left = rest(left) else append first(right) to result right = rest(right) if length(left) > 0 append rest(left) to result if length(right) > 0 append rest(right) to result return result 2.3.2 Optimizando merge sort En los ordenadores modernos, el principio de localidad puede ser primordial en la optimización de software, porque se usan jerarquías de memoria multi-nivel. Se han propuesto versiones de cache-consciente del algoritmo de ordenación por mezcla, cuyas operaciones han sido espeEjemplo de ordenamiento por mezcla. cíficamente escogidas para minimizar el movimiento de entrada y salida de páginas de la memoria caché de la máquina. Por ejemplo, el algorimo “tiled merge sort” deja de particionar subarrays cuando se han alcanzado subarrays 2.3.1 Descripción de tamaño S, donde S es el número de elementos que caFue desarrollado en 1945 por John Von Neumann ben en una única página en memoria. Cada uno de esos subarrays se ordenan con un algorimo de ordenación in.[cita requerida] situ, para evitar intercambios en memoria, y entonces se Conceptualmente, el ordenamiento por mezcla funciona termina con el algoritmo de ordenamiento por mezcla en de la siguiente manera: su versión recursiva estándar. Este algoritmo ha demostrado un mejor rendimiento en máquinas que se benefi1. Si la longitud de la lista es 0 ó 1, entonces ya está cian de la optimización caché. ordenada. En otro caso: M.A. Kronrod sugirió en 1969 una versión alternativa del 2. Dividir la lista desordenada en dos sublistas de apro- algoritmo de ordenamiento por mezcla que usaba espacio adicional constante. Este algoritmo fue refinado por Kaximadamente la mitad del tamaño. tajainen, Pasanen y Teuhola. 3. Ordenar cada sublista recursivamente aplicando el ordenamiento por mezcla. 4. Mezclar las dos sublistas en una sola lista ordenada. 2.3.3 Comparación con otros algoritmos de ordenamiento El ordenamiento por mezcla incorpora dos ideas princi- Aunque heapsort tiene los mismos límites de tiempo que pales para mejorar su tiempo de ejecución: merge sort, requiere sólo Θ(1) espacio auxiliar en lugar 2.5. HEAPSORT del Θ(n) de merge sort, y es a menudo más rápido en implementaciones prácticas. Quicksort, sin embargo, es considerado por mucho como el más rápido algoritmo de ordenamiento de propósito general. En el lado bueno, merge sort es un ordenamiento estable, paraleliza mejor, y es más eficiente manejando medios secuenciales de acceso lento. Merge sort es a menudo la mejor opción para ordenar una lista enlazada: en esta situación es relativamente fácil implementar merge sort de manera que sólo requiera Θ(1) espacio extra, y el mal rendimiento de las listas enlazadas ante el acceso aleatorio hace que otros algoritmos (como quicksort) den un bajo rendimiento, y para otros (como heapsort) sea algo imposible. (EL PELON) 7 mazo de cartas numeradas en forma arbitraria. Requiere O(n²) operaciones para ordenar una lista de n elementos. Inicialmente se tiene un solo elemento, que obviamente es un conjunto ordenado. Después, cuando hay k elementos ordenados de menor a mayor, se toma el elemento k+1 y se compara con todos los elementos ya ordenados, deteniéndose cuando se encuentra un elemento menor (todos los elementos mayores han sido desplazados una posición a la derecha) o cuando ya no se encuentran elementos (todos los elementos fueron desplazados y este es el más pequeño). En este punto se inserta el elemento k+1 debiendo desplazarse los demás elementos. 2.4.1 Véase también Para Perl 5.8, merge sort es el algoritmo de ordenamiento por defecto (lo era quicksort en versiones anteriores de • Algoritmo de ordenamiento Perl). En Java los métodos de ordenación de Arrays usan merge sort o una modificación de quicksort dependiendo de los tipos de datos y por cuestiones de eficiencia cam- 2.4.2 Enlaces externos bian a ordenamiento por inserción cuando se están ordenando menos de siete elementos en el array. .,., • Distintas implementaciones del algoritmo en Wikibooks (inglés) 2.3.4 Enlaces externos • Distintas implementaciones del algoritmo en Wikibooks (inglés) • Distintas implementaciones del algoritmo en RosettaCode.org (inglés) • Distintas implementaciones del algoritmo en RosettaCode.org (inglés) 2.5 Heapsort Bibliotecas • Sort::Merge Módulo Perl en CPAN • File::MergeSort Módulo Perl en CPAN 2.4 Ordenamiento por inserción Animación mostrando el funcionamiento del heapsort. El ordenamiento por montículos (heapsort en inglés) es un algoritmo de ordenamiento no recursivo, no estable, con complejidad computacional Θ(n log n) Este algoritmo consiste en almacenar todos los elementos del vector a ordenar en un montículo (heap), y luego extraer el nodo que queda como nodo raíz del montícuEjemplo de ordenamiento por inserción ordenando una lista de lo (cima) en sucesivas iteraciones obteniendo el conjunto números aleatorios. ordenado. Basa su funcionamiento en una propiedad de El ordenamiento por inserción (insertion sort en los montículos, por la cual, la cima contiene siempre el inglés) es una manera muy natural de ordenar para un menor elemento (o el mayor, según se haya definido el ser humano, y puede usarse fácilmente para ordenar un montículo) de todos los almacenados en él. El algoritmo, 8 CAPÍTULO 2. CLASIFICACION después de cada extracción, recoloca en el nodo raíz o cima, la última hoja por la derecha del último nivel. Lo cual destruye la propiedad heap del árbol. Pero, a continuación realiza un proceso de “descenso” del número insertado de forma que se elige a cada movimiento el mayor de sus dos hijos, con el que se intercambia. Este intercambio, realizado sucesivamente “hunde” el nodo en el árbol restaurando la propiedad montículo del arbol y dejándo paso a la siguiente extracción del nodo raíz. El algoritmo, en su implementación habitual, tiene dos fases. Primero una fase de construcción de un montículo a partir del conjunto de elmentos de entrada, y después, una fase de extracción sucesiva de la cima del montículo. La implementación del almacén de datos en el heap, pese a ser conceptualmente un árbol, puede realizarse en un vector de forma fácil. Cada nodo tiene dos hijos y por tanto, un nodo situado en la posición i del vector, tendrá a sus hijos en las posiciones 2 x i, y 2 x i +1 suponiendo que el primer elemento del vector tiene un índice = 1. Es decir, la cima ocupa la posición inicial del vector y sus dos hijos la posición segunda y tercera, y así, sucesivamente. Por tanto, en la fase de ordenación, el intercambio ocurre entre el primer elemento del vector (la raíz o cima del árbol, que es el mayor elemento del mismo) y el último elemento del vector que es la hoja más a la derecha en el último nivel. El árbol pierde una hoja y por tanto reduce su tamaño en un elemento. El vector definitivo y ordenado, empieza a construirse por el final y termina por el principio. 2.5.1 Descripción He aquí una descripción en pseudocódigo del algoritmo. Se pueden encontrar descripciones de las operaciones insertar_en_monticulo y extraer_cima_del_monticulo en el artículo sobre montículos. function heapsort(array A[0..n]): montículo M integer i := 124578 for i = 0..n: insertar_en_monticulo(M, A[i]) for i = 0..n: A[i] = extraer_cima_del_monticulo(M) return A 2.5.2 Enlaces externos • Distintas implementaciones del algoritmo en Wikibooks (inglés) • Distintas implementaciones del algoritmo en RosettaCode.org (inglés) Capítulo 3 Text and image sources, contributors, and licenses 3.1 Text • Algoritmo de búsqueda Fuente: http://es.wikipedia.org/wiki/Algoritmo%20de%20b%C3%BAsqueda?oldid=81114917 Colaboradores: Makz~eswiki, Ascánder, Symonblade, Stan Shebs, Renabot, Caos, Airunp, Taichi, Emijrp, Rembiapo pohyiete (bot), Genba, Drini2, RobotQuistnix, Chobot, Yrbot, GermanX, KnightRider, Jesuja, Facon, Kn, CEM-bot, EnWILLYado, BlackSalamander, FrancoGG, Ggenellina, DominicanZero, MSBOT, Soulbot, DerHexer, Ejconquer, Ofuentesgual, Biasoli, VolkovBot, Technopat, Pmontaldo, Synthebot, Carmel2007, Edmenb, YonaBot, Cobalttempest, Farisori, Michada~eswiki, Gökhan, AVBOT, MastiBot, DiegoFb, Vic Fede, Jorge Dueñas Lerín, Xqbot, Jkbw, Botarel, Halfdrag, Dacripo, GrouchoBot, Kasirbot, MerlIwBot, KLBot2, Isacdaavid, Ramzysamman, Crystallizedcarbon, Sergioperezeci y Anónimos: 65 • Algoritmo de agrupamiento Fuente: http://es.wikipedia.org/wiki/Algoritmo%20de%20agrupamiento?oldid=80530746 Colaboradores: Jjmerelo, Tano4595, Ecemaml, Rembiapo pohyiete (bot), RobotQuistnix, TCrossland~eswiki, FlaBot, BOTijo, Equi, Alfredobi, Thijs!bot, Cgb, JAnDbot, TXiKiBoT, Juan renombrado, SieBot, Loveless, Juan Mayordomo, AVBOT, Pssuils, Diegusjaimes, Luckas-bot, DiegoFb, Erud, Xqbot, D'ohBot, EmBOTellado, MondalorBot, Ripchip Bot, EmausBot, ZéroBot, ChuispastonBot, TransportObserver, KLBot2, Solvete y Anónimos: 14 • Quicksort Fuente: http://es.wikipedia.org/wiki/Quicksort?oldid=82219175 Colaboradores: Pino, Pablo.cl, JorgeGG, Fortran~eswiki, Ascánder, Sms, Tostadora, Jacobo Tarrio, Porao, Renabot, Wariou, Boticario, JMPerez, Rembiapo pohyiete (bot), Human~eswiki, Dem, CarlosHoyos, RobotQuistnix, Yrbot, YurikBot, Gaboto, GermanX, Gothmog, Joanumbert, BOTpolicia, CEM-bot, Gafotas, Thijs!bot, JoaquinFerrero, Juen, Xavigivax, Dealonso, Netito777, VolkovBot, Matdrodes, Elabra sanchez, Muro Bot, BotMultichill, DevilishFreak, SieBot, Loveless, Rafael josem, STBot~eswiki, PipepBot, Yonseca, Eduardosalg, LordT, Chebi~eswiki, Raulshc, Camilo, Paredero, UA31, Arlm1000, AVBOT, Louperibot, Mkucharuk, DumZiBoT, Papagorila, Manuelt15, Jkbw, Aclapes, Igna, Pandemon~eswiki, Execoot~eswiki, Kelwin, LevanenG, Yago AB, KamikazeBot, Tarawa1943, Savh, J. A. Gélvez, ChuispastonBot, Xerox 5B, Rezabot, JotaMC, YFdyh-bot, Pepetacos, Addbot, Ambigus9, Milder.q, Jatch21, Holahalou y Anónimos: 134 • Ordenamiento por mezcla Fuente: http://es.wikipedia.org/wiki/Ordenamiento%20por%20mezcla?oldid=81964250 Colaboradores: Xykatra, Ascánder, Sms, Jacobo Tarrio, Boticario, Aeveraal, Rembiapo pohyiete (bot), Dem, RobotQuistnix, Yrbot, FlaBot, BOTijo, Thijs!bot, Escarbot, JoaquinFerrero, JAnDbot, JulGor, Muro de Aguas, Biasoli, VolkovBot, Aliamondano, Shooke, BotMultichill, SieBot, PipepBot, DragonBot, UA31, Albambot, AVBOT, Diegusjaimes, Macro.masek, Luckas-bot, Shekatsu8er, ArthurBot, Jkbw, Ricardogpn, TobeBot, Halfdrag, RedBot, Kelwin, EmausBot, Savh, Grillitus, Paulopin, V!rus, Riemann’sZeta, STANHMAL, Emferr, Addbot, Damnerpalacios, Cfsalguero, Halcydez y Anónimos: 59 • Ordenamiento por inserción Fuente: http://es.wikipedia.org/wiki/Ordenamiento%20por%20inserci%C3%B3n?oldid=82086229 Colaboradores: Pablo.cl, ManuelGR, Sms, Tano4595, Boticario, Rembiapo pohyiete (bot), Drini2, CarlosHoyos, Orgullobot~eswiki, RobotQuistnix, Yrbot, BOTijo, GermanX, Gothmog, Jesuja, Milestones, Kn, CEM-bot, Laura Fiorucci, Thijs!bot, JoaquinFerrero, JAnDbot, Muro de Aguas, TXiKiBoT, AlnoktaBOT, VolkovBot, Ndarkduck, Technopat, Lahi, Carmel2007, 3coma14, Muro Bot, SieBot, Loveless, Manuelhosto, Dnu72, HUB, SilvonenBot, AVBOT, MastiBot, Ockie, Diegusjaimes, Arjuno3, InflaBOT, WikiDreamer Bot, XZeroBot, Albertochoa, Botarel, Josemariovanegas, Fitoschido, Dinamik-bot, Ripchip Bot, ChuispastonBot, Jr JL, Alexsugasti, Addbot, Maub1985 y Anónimos: 114 • Heapsort Fuente: http://es.wikipedia.org/wiki/Heapsort?oldid=74152700 Colaboradores: Dodo, Triku, Ascánder, Sms, Jacobo Tarrio, Taragui, Boticario, Emijrp, Rembiapo pohyiete (bot), RobotQuistnix, Chobot, Yrbot, BOTijo, GermanX, CEM-bot, Santhy, Montgomery, Thijs!bot, JoaquinFerrero, JAnDbot, Biasoli, VolkovBot, Matdrodes, Elabra sanchez, SieBot, STBot~eswiki, DragonBot, Bgangioni, Louperibot, MelancholieBot, Luckas-bot, Jotterbot, Rotovator, Mcapdevila, Xqbot, Ripchip Bot, J. A. Gélvez, Maucendon, Addbot y Anónimos: 20 3.2 Images • Archivo:Commons-logo.svg Fuente: http://upload.wikimedia.org/wikipedia/commons/4/4a/Commons-logo.svg Licencia: Public domain Colaboradores: This version created by Pumbaa, using a proper partial circle and SVG geometry features. (Former versions used to be slightly 9 10 CAPÍTULO 3. TEXT AND IMAGE SOURCES, CONTRIBUTORS, AND LICENSES warped.) Artista original: SVG version was created by User:Grunt and cleaned up by 3247, based on the earlier PNG version, created by Reidab. • Archivo:Insertion-sort-example-300px.gif Fuente: http://upload.wikimedia.org/wikipedia/commons/0/0f/ Insertion-sort-example-300px.gif Licencia: CC BY-SA 3.0 Colaboradores: Trabajo propio Artista original: Swfung8 • Archivo:Merge-sort-example-300px.gif Fuente: http://upload.wikimedia.org/wikipedia/commons/c/cc/Merge-sort-example-300px. gif Licencia: CC BY-SA 3.0 Colaboradores: Trabajo propio Artista original: Swfung8 • Archivo:Sorting_heapsort_anim.gif Fuente: http://upload.wikimedia.org/wikipedia/commons/1/1b/Sorting_heapsort_anim.gif Licencia: CC-BY-SA-3.0 Colaboradores: http://de.wikipedia.org/wiki/Image:Sorting_heapsort_anim.gif, own work Artista original: de:User: RolandH • Archivo:Sorting_quicksort_anim.gif Fuente: http://upload.wikimedia.org/wikipedia/commons/6/6a/Sorting_quicksort_anim.gif Licencia: CC-BY-SA-3.0 Colaboradores: originally upload on the English Wikipedia Artista original: Wikipedia:en:User:RolandH 3.3 Content license • Creative Commons Attribution-Share Alike 3.0
© Copyright 2024