22/05/13

Algoritmos de ordenamiento. Capítulo quicksort

C++ con Clase Algoritmos de ordenamiento Algoritmos de ordenamiento Estilo: Normal Activar Visitas desde 2000-09-09 Usuarios en línea Con Clase C++ Win API 32 HTML y CSS Gráficos MySQL Artículos Listas << < > >> Curso Info Bibliotecas Tabla Comentario Algoritmos de ordenamiento 1 Ordenamiento Burbuja 2 Ordenamiento por Selección 3 Ordenamiento por Inserción 4 Ordenamiento Quicksort Descripción Pseudocódigo en C Un ejemplo Optimizando Análisis del algoritmo

4 Ordenamiento Rápido (Quicksort)
^

1. Descripción.
^
c.conclase.net/orden/?cap=quicksort 1/6

Repites esto hasta que se crucen los índices. de manera que a un lado queden todos los menores que él y al otro los mayores (explicado más abajo también). Al finalizar este procedimiento el elemento de división queda en una posición en que todos los elementos a su izquierda son menores que él. para que se cumpla la condición y pueda aplicarse la recursividad. Capítulo quicksort Esta es probablemente la técnica más rápida conocida. Pero luego habría que mover todos estos elementos a la izquierda del elemento. Reflexionando un poco más se obtiene un procedimiento mucho más efectivo. y j. al que llamaremos contador por la derecha. Lo llamaremos elemento de división. El algoritmo es éste: Recorres la lista simultáneamente con i y j: por la izquierda con i (desde el primer elemento).net/orden/?cap=quicksort 2/6 .22/05/13 Algoritmos de ordenamiento. El algoritmo fundamental es el siguiente: Eliges un elemento de la lista. Realizas esto de forma recursiva para cada sublista mientras éstas tengan un largo mayor que 1.A. y los que están a su derecha son mayores. ^ Tabla de variables Nombre lista inf sup temp i j cont Cualquiera Entero Entero Tipo Lista a ordenar Elemento inferior de la lista Elemento superior de la lista Uso elem_div El mismo que los elementos de la lista El elemento divisor El mismo que los elementos de la lista Para realizar los intercambios Entero Entero Entero Contador por la izquierda Contador por la derecha El ciclo continua mientras cont tenga el valor 1 N o m b r eP r o c e d i m i e n t o :O r d R a p c. Pseudocódigo en C. Cuando lista[i] sea mayor que el elemento de división y lista[j] sea menor los intercambias. Se utilizan dos índices: i. porque sabemos que a un lado los elementos son todos menores y al otro son todos mayores (o habrían sido intercambiados). Una vez terminado este proceso todos los elementos estarán ordenados. Fue desarrollada por C.R. Una idea preliminar para ubicar el elemento de división en su posición final sería contar la cantidad de elementos menores y colocarlo un lugar más arriba. El algoritmo original es recursivo. Puede ser cualquiera (en Optimizando veremos una forma más efectiva).conclase. El punto en que se cruzan los índices es la posición adecuada para colocar el elemento de división. al que llamaremos contador por la izquierda. y consumen más recursos). Buscas la posición que le corresponde en la lista ordenada (explicado más abajo). 2. y por la derecha con j (desde el último elemento). Hoare en 1960. En este momento el elemento de división separa la lista en dos sublistas (de ahí su nombre). pero se utilizan versiones iterativas para mejorar su rendimiento (los algoritmos recursivos son en general más lentos que los iterativos. Acomodas los elementos de la lista a cada lado del elemento de división.

1 0 . / /C o p i a m o se le l e m e n t od ed i v i s i ó n / /e ns up o s i c i ó nf i n a l 1 6 . 9 . Un ejemplo ^ Esta vez voy a cambiar de lista . r e t o r n a r .i f( i n f> =s u p ) 6 .i+1 .e l e m _ d i v=l i s t a [ s u p ] . Intercambiamos: c.i=i n f-1 .s u p ) . 1 8 .c o n t=1 . 2 0 . w h i l e( l i s t a [ + + i ]<e l e m _ d i v ) . Capítulo quicksort P a r á m e t r o s : l i s t aao r d e n a r( l i s t a ) í n d i c ei n f e r i o r( i n f ) í n d i c es u p e r i o r( s u p ) / /I n i c i a l i z a c i ó nd ev a r i a b l e s 1 . w h i l e( l i s t a [ j ]>e l e m _ d i v ) . / / C l a s i f i c a m o sl as u b l i s t a 7 . l i s t a [ j ]=t e m p . / /A p l i c a m o se lp r o c e d i m i e n t o / /r e c u r s i v a m e n t eac a d as u b l i s t a 1 9 . 3 . 1 7 . t e m p=l i s t a [ i ] . 5-3-7-6-2-1-4 5 es mayor que cuatro y 1 es menor. 1 3 .l i s t a [ s u p ]=t e m p . 1 2 .conclase. 3. Nota: La primera llamada debería ser con la lista. El elemento divisor será el 4: 5-3-7-6-2-1-4 Comparamos con el 5 por la izquierda y el 1 por la derecha.O r d R a p( l i s t a . 1 4 . 2 .22/05/13 Algoritmos de ordenamiento.net/orden/?cap=quicksort 3/6 . l i s t a [ i ]=l i s t a [ j ] .-D 5-3-7-6-2-1-4 Comenzamos con la lista completa.w h i l e( c o n t ) 8 .i n f . / /V e r i f i c a m o sq u en os ec r u c e nl o sl í m i t e s 5 .t e m p=l i s t a [ i ] .O r d R a p( l i s t a . 4 .l i s t a [ i ]=l i s t a [ s u p ] . i f( i<j ) 1 1 .i-1 ) . e l s e 1 5 . cero (0) y el tamaño de la lista menos 1 como parámetros. c o n t=0 .j=s u p .

2 es menor que 4: nos mantenemos ahí. 3 es mayor: avanzamos por la derecha. Ahora intercambiamos lista[i] con lista[sup] (pasos 16-18): 1-3-2-4-7-5-6 Aplicamos recursivamente a la sublista de la izquierda (índices 0 . Se intercambia lista[i] con lista[sup]: 1-2-3 Al llamar recursivamente para cada nueva sublista (lista[0]-lista[0] y lista[2]-lista[2]) se retorna sin hacer cambios (condición 5. porque los índices se cruzaron.). Tenemos lo siguiente: 1-3-2 1 es menor que 2: avanzamos por la izquierda.Para resumir te muestro cómo va quedando la lista: Segunda sublista: lista[4]-lista[6] 7-5-6 5-7-6 5-6-7 Para cada nueva sublista se retorna sin hacer cambios (se cruzan los índices).conclase. Capítulo quicksort 1-3-7-6-2-5-4 Avanzamos por la izquierda y la derecha: 1-3-7-6-2-5-4 3 es menor que 4: avanzamos por la izquierda.net/orden/?cap=quicksort 4/6 . Optimizando. 1-3-2-6-7-5-4 Avanzamos por ambos lados: 1-3-2-6-7-5-4 En este momento termina el ciclo principal. Finalmente. 1-3-7-6-2-5-4 7 es mayor que 4 y 2 es menor: intercambiamos. c. Bastante largo ¿verdad? 4. al retornar de la primera llamada se tiene el arreglo ordenado: 1-2-3-4-5-6-7 Eso es todo. Como se intercambiaron los índices termina el ciclo.22/05/13 Algoritmos de ordenamiento.2).

^ Estabilidad: No es estable. 5. Elección del elemento de división: Se elige desde un conjunto de tres elementos: lista[inferior]. Al terminar la clasificación se llama a otro algoritmo de ordenamiento que termine la labor.conclase. En su forma iterativa la necesita para la pila. En este caso el rendimiento se degrada a O(n2). No clasificar todas las sublistas: Cuando el largo de las sublistas va disminuyendo. Cada sublista genera en promedio dos sublistas más de largo n/2. Esto evita el comportamiento degenerado cuando la lista está prácticamente ordenada. Para solucionarlo sólo se clasifican las listas que tengan un largo menor que n. El peor caso ocurre cuando la lista ya está ordenada. Desventajas: Implementación un poco más complicada. Capítulo quicksort ^ Sólo voy a mencionar algunas optimizaciones que pueden mejorar bastante el rendimiento de quicksort: Hacer una versión iterativa: Para ello se utiliza una pila en que se van guardando los límites superior e inferior de cada sublista. La elección de n depende de varios factores. Ventajas: Muy rápido No requiere memoria adicional. lista[mitad] y lista[superior]. pero un valor entre 10 y 25 es adecuado. La complejidad para dividir una lista de n es O(n).22/05/13 Algoritmos de ordenamiento. Requerimientos de Memoria: No requiere memoria adicional en su forma recursiva. Por lo tanto la complejidad se define en forma recurrente como: f(1) = 1 f(n) = n + 2 f(n/2) La forma cerrada de esta expresión es: f(n) = n log2n Es decir. El indicado es uno que se comporte bien con listas casi ordenadas. como el ordenamiento por inserción por ejemplo. la complejidad es O(n log2 n). Tiempo de Ejecución: Caso promedio. Con las optimizaciones mencionadas arriba puede evitarse este comportamiento.net/orden/?cap=quicksort 5/6 . c. Análisis del algoritmo. porque cada llamada genera sólo una sublista (todos los elementos son menores que el elemento de división). El elemento elegido es el que tenga el valor medio según el criterio de comparación. el proceso se va encareciendo.

Mucha diferencia entre el peor y el mejor caso.cl c.conclase. thank you so much © Diciembre de 2001.net/orden/?cap=quicksort 6/6 .22/05/13 Algoritmos de ordenamiento. Comentarios de los usuarios (1) ESMERALDA FLORES DEL RIO 2011-02-13 04:34:28 El trabajo de algoritmos de ordenamiento. La mayoría de los problemas de rendimiento se pueden solucionar con las optimizaciones mencionadas arriba (al costo de complicar mucho más la implementación). jhida003@pinhue. Este es un algoritmo que puedes utilizar en la vida real.Fue de gran ayuda para realizar una tarea en equipo para mi clase de cibernética. Es muy eficiente. Mira el código si tienes dudas.ufro. Intenta programarlo. Capítulo quicksort Recursividad (utiliza muchos recursos). Julián Hidalgo. En general será la mejor opción.

Sign up to vote on this title
UsefulNot useful