¿No sabes por dónde empezar? Ayúdanos normalizando artículos.
¿Tienes experiencia? Crea alguno de estos artículos de actualidad.

Diferencia entre revisiones de «QuickSort»

(Página creada con '{{Definición |nombre=Ordenamiento por Quicksort |imagen=Quicksort.gif |tamaño= |concepto= }} '''El ordenamiento rápido,''' '''quicksort '''en inglés: Es un [[...')
 
m
Línea 5: Línea 5:
 
|concepto=
 
|concepto=
 
}}
 
}}
 +
  
'''El ordenamiento rápido,''' '''[[quicksort|quicksort]] '''en inglés: Es un [[algoritmo|algoritmo]] 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.
+
'''El ordenamiento rápido,''' '''[[Quicksort|quicksort]] '''en inglés: Es un [[Algoritmo|algoritmo]] 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.
 
+
  
 +
<br>
 +
  
== Descripción del algoritmo ==
+
== Descripción del algoritmo ==
  
 
El algoritmo consta de los siguientes pasos:
 
El algoritmo consta de los siguientes pasos:
 +
  
#Elegir un elemento de la lista de elementos a ordenar, al que llamaremos [[pivote|pivote]].
+
#Elegir un elemento de la lista de elementos a ordenar, al que llamaremos [[Pivote|pivote]].
#Resituar los demás 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 [[implementación|implementación]] deseada. En este momento, el pivote ocupa exactamente el lugar que le corresponderá en la lista ordenada.
+
 +
#Resituar los demás 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 [[Implementación|implementación]] deseada. En este momento, el pivote ocupa exactamente el lugar que le corresponderá en la lista ordenada.
 +
 
#La lista queda separada en dos sublistas, una formada por los elementos a la izquierda del pivote, y otra por los elementos a su derecha.
 
#La lista queda separada en dos sublistas, una formada por los elementos a la izquierda del pivote, y otra por los elementos a su derecha.
 +
 
#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.
 
#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.
  
 +
<br>
 +
  
 +
== Eficiencia del algoritmo  ==
  
== Eficiencia del algoritmo ==
+
La [[Eficiencia del algoritmo|eficiencia del algoritmo]] depende de la posición en la que termine el pivote elegido.<br>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|complejidad del algoritmo]] es O(n•log n).<br>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.<br>En el caso promedio, el orden es O(n•log n). Y no es extraño, pues, que la mayoría de [[Optimizaciones|optimizaciones]] que se aplican al algoritmo se centren en la elección del pivote.
 +
  
La [[eficiencia del algoritmo|eficiencia del algoritmo]] depende de la posición en la que termine el pivote elegido.<br>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|complejidad del algoritmo]] es O(n•log n).<br>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.<br>En el caso promedio, el orden es O(n•log n). Y no es extraño, pues, que la mayoría de [[optimizaciones|optimizaciones]] que se aplican al algoritmo se centren en la elección del pivote.
+
== <br>Demostración ==
 
 
== <br>Demostración ==
 
  
 
Suponiendo que el número total de elementos a ordenar es potencia de dos, es decir, n = 2k. De aquí podemos ver que k = log2(n), donde k es el número de divisiones que realizará el algoritmo.
 
Suponiendo que el número total de elementos a ordenar es potencia de dos, es decir, n = 2k. De aquí podemos ver que k = log2(n), donde k es el número de divisiones que realizará el algoritmo.
 +
  
 
En la primera fase del algoritmo habrán n comparaciones, en la segunda fase el algoritmo creará dos sublistas aproximadamente de tamaño n/2. El número total de comparaciones de estas dos sublistas es: 2(n/2) = n. En la tercera fase el algoritmo procesará 4 sublistas más, por tanto el número total de comparaciones en esta fase es 4(n/4) = n.
 
En la primera fase del algoritmo habrán n comparaciones, en la segunda fase el algoritmo creará dos sublistas aproximadamente de tamaño n/2. El número total de comparaciones de estas dos sublistas es: 2(n/2) = n. En la tercera fase el algoritmo procesará 4 sublistas más, por tanto el número total de comparaciones en esta fase es 4(n/4) = n.
 +
  
 
En conclusión, el número total de comparaciones que hace el algoritmo es:
 
En conclusión, el número total de comparaciones que hace el algoritmo es:
 +
  
 
n + n + n + ..... + n = kn, donde k = log2(n), por tanto el tiempo de ejecución del algoritmo en el mejor caso es O(n.log2n)
 
n + n + n + ..... + n = kn, donde k = log2(n), por tanto el tiempo de ejecución del algoritmo en el mejor caso es O(n.log2n)
 +
  
== <br>Optimización del algoritmo ==
+
== <br>Optimización del algoritmo ==
  
 
Cabe destacar que de usarse en su versión recursiva las siguientes optimizaciones y sus desventajas no se ven vistas en el tiempo de ejecución del mismo manteniéndose, así el tiempo de ejecución planteado en un principio.
 
Cabe destacar que de usarse en su versión recursiva las siguientes optimizaciones y sus desventajas no se ven vistas en el tiempo de ejecución del mismo manteniéndose, así el tiempo de ejecución planteado en un principio.
 +
  
== <br>Técnicas de elección del pivote ==
+
== <br>Técnicas de elección del pivote ==
  
 
El algoritmo básico del método Quicksort consiste en tomar cualquier elemento de la lista al cual denominaremos como pivote, dependiendo de la partición en que se elija, el algoritmo será más o menos eficiente.<br>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.<br>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 cálculo adicional rebaja bastante la eficiencia del algoritmo en el caso promedio.<br>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.
 
El algoritmo básico del método Quicksort consiste en tomar cualquier elemento de la lista al cual denominaremos como pivote, dependiendo de la partición en que se elija, el algoritmo será más o menos eficiente.<br>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.<br>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 cálculo adicional rebaja bastante la eficiencia del algoritmo en el caso promedio.<br>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.
 +
  
== <br>Técnicas de reposicionamiento ==
+
== <br>Técnicas de reposicionamiento ==
  
Una idea preliminar para ubicar el pivote en su posición 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 pueda aplicarse la [[recursividad|recursividad]].
+
Una idea preliminar para ubicar el pivote en su posición 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 pueda aplicarse la [[Recursividad|recursividad]].
 +
  
 
Existe, no obstante, un procedimiento mucho más efectivo. Se utilizan dos índices: i, al que llamaremos índice izquierdo, y j, al que llamaremos índice derecho. El algoritmo es el siguiente:
 
Existe, no obstante, un procedimiento mucho más efectivo. Se utilizan dos índices: i, al que llamaremos índice izquierdo, y j, al que llamaremos índice derecho. El algoritmo es el siguiente:
 +
  
 
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).<br>Cuando lista[i] sea mayor que el pivote y lista[j] sea menor, se intercambian los elementos en esas posiciones.
 
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).<br>Cuando lista[i] sea mayor que el pivote y lista[j] sea menor, se intercambian los elementos en esas posiciones.
 +
  
 
Repetir esto hasta que se crucen los índices.<br>El punto en que se cruzan los índices es la posición adecuada para colocar el pivote, porque sabemos que a un lado los elementos son todos menores y al otro son todos mayores (o habrían sido intercambiados).
 
Repetir esto hasta que se crucen los índices.<br>El punto en que se cruzan los índices es la posición adecuada para colocar el pivote, porque sabemos que a un lado los elementos son todos menores y al otro son todos mayores (o habrían sido intercambiados).
 +
  
== <br>Parámetros:&nbsp; ==
+
== <br>Parámetros:&nbsp; ==
  
 
#Se debe llamar a la función Quicksort desde donde quiera ejecutarse
 
#Se debe llamar a la función Quicksort desde donde quiera ejecutarse
 +
 
#Ésta llamará a colocar pivote para encontrar el valor del mismo
 
#Ésta llamará a colocar pivote para encontrar el valor del mismo
 +
 
#Se ejecutará el algoritmo Quicksort de forma recursiva a ambos lados del pivote
 
#Se ejecutará el algoritmo Quicksort de forma recursiva a ambos lados del pivote
  
 
<br>int colocar(int *v, int b, int t)<br>{<br> int i;<br> int pivote, valor_pivote;<br> int temp;<br> <br> pivote = b;<br> valor_pivote = v[pivote];<br> for (i=b+1; i&lt;=t; i++){<br> if (v[i] &lt; valor_pivote){<br> pivote++; <br> temp=v[i];<br> v[i]=v[pivote];<br> v[pivote]=temp;<br> <br> }<br> }<br> temp=v[b];<br> v[b]=v[pivote];<br> v[pivote]=temp;<br> return pivote;<br>} <br> void Quicksort(int* v, int b, int t)<br>{<br> int pivote;<br> if(b &lt; t){<br> pivote=colocar(v, b, t);<br> Quicksort(v, b, pivote-1);<br> Quicksort(v, pivote+1, t);<br> } <br>}
 
<br>int colocar(int *v, int b, int t)<br>{<br> int i;<br> int pivote, valor_pivote;<br> int temp;<br> <br> pivote = b;<br> valor_pivote = v[pivote];<br> for (i=b+1; i&lt;=t; i++){<br> if (v[i] &lt; valor_pivote){<br> pivote++; <br> temp=v[i];<br> v[i]=v[pivote];<br> v[pivote]=temp;<br> <br> }<br> }<br> temp=v[b];<br> v[b]=v[pivote];<br> v[pivote]=temp;<br> return pivote;<br>} <br> void Quicksort(int* v, int b, int t)<br>{<br> int pivote;<br> if(b &lt; t){<br> pivote=colocar(v, b, t);<br> Quicksort(v, b, pivote-1);<br> Quicksort(v, pivote+1, t);<br> } <br>}
 +
  
 
Nota: Los tres parámetros de la llamada inicial a Quicksort serán array[0], 0, numero_elementos -1, es decir, si es un array de 6 elementos array[0], 0, 5
 
Nota: Los tres parámetros de la llamada inicial a Quicksort serán array[0], 0, numero_elementos -1, es decir, si es un array de 6 elementos array[0], 0, 5
 +
  
 +
<br>
 +
  
 +
<br>
 +
  
 
+
== Implementación del Pseudocódigo ==
 
 
== Implementación del Pseudocódigo ==
 
  
 
function quicksort(array)<br> var list, less, greater<br> if length(array) ≤ 1<br> return array<br> seleccionar y eliminar un valor pivote pivot en el array<br> for each x in array<br> if x &lt; pivot then añadir x a less<br> else añadir x a greater<br> return concadenar(quicksort(less), pivot, quicksort(greater))
 
function quicksort(array)<br> var list, less, greater<br> if length(array) ≤ 1<br> return array<br> seleccionar y eliminar un valor pivote pivot en el array<br> for each x in array<br> if x &lt; pivot then añadir x a less<br> else añadir x a greater<br> return concadenar(quicksort(less), pivot, quicksort(greater))
 +
  
== <br>Ejemplo ==
+
== <br>Ejemplo ==
 
 
 
 
  
 
En el siguiente ejemplo se marcan el pivote y los índices i y j con las letras p, i y j respectivamente.
 
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:<br>5 - 3 - 7 - 6 - 2 - 1 - 4<br> p
 
Comenzamos con la lista completa. El elemento pivote será el 4:<br>5 - 3 - 7 - 6 - 2 - 1 - 4<br> p
 +
  
 
<br>Comparamos con el 5 por la izquierda y el 1 por la derecha.<br>5 - 3 - 7 - 6 - 2 - 1 - 4 <br>i j p
 
<br>Comparamos con el 5 por la izquierda y el 1 por la derecha.<br>5 - 3 - 7 - 6 - 2 - 1 - 4 <br>i j p
 +
  
 
<br>5 es mayor que 4 y 1 es menor. Intercambiamos:<br>1 - 3 - 7 - 6 - 2 - 5 - 4<br>i j p  
 
<br>5 es mayor que 4 y 1 es menor. Intercambiamos:<br>1 - 3 - 7 - 6 - 2 - 5 - 4<br>i j p  
 +
  
 
<br>Avanzamos por la izquierda y la derecha:<br>1 - 3 - 7 - 6 - 2 - 5 - 4<br> i j p  
 
<br>Avanzamos por la izquierda y la derecha:<br>1 - 3 - 7 - 6 - 2 - 5 - 4<br> i j p  
 +
  
 
<br>3 es menor que 4: avanzamos por la izquierda. 2 es menor que 4: nos mantenemos ahí.<br>1 - 3 - 7 - 6 - 2 - 5 - 4<br> i j p  
 
<br>3 es menor que 4: avanzamos por la izquierda. 2 es menor que 4: nos mantenemos ahí.<br>1 - 3 - 7 - 6 - 2 - 5 - 4<br> i j p  
 +
  
 
<br>7 es mayor que 4 y 2 es menor: intercambiamos.<br>1 - 3 - 2 - 6 - 7 - 5 - 4<br> i j p  
 
<br>7 es mayor que 4 y 2 es menor: intercambiamos.<br>1 - 3 - 2 - 6 - 7 - 5 - 4<br> i j p  
 +
  
 
<br>Avanzamos por ambos lados:<br>1 - 3 - 2 - 6 - 7 - 5 - 4<br> iyj p  
 
<br>Avanzamos por ambos lados:<br>1 - 3 - 2 - 6 - 7 - 5 - 4<br> iyj p  
 +
  
 
<br>En este momento termina el ciclo principal, porque los índices se cruzaron. Ahora intercambiamos lista[i] con lista[sup] (pasos 16-18):<br>1 - 3 - 2 - 4 - 7 - 5 - 6<br> p  
 
<br>En este momento termina el ciclo principal, porque los índices se cruzaron. Ahora intercambiamos lista[i] con lista[sup] (pasos 16-18):<br>1 - 3 - 2 - 4 - 7 - 5 - 6<br> p  
 +
  
 
<br>Aplicamos recursivamente a la sublista de la izquierda (índices 0 - 2). Tenemos lo siguiente:<br>1 - 3 - 2  
 
<br>Aplicamos recursivamente a la sublista de la izquierda (índices 0 - 2). Tenemos lo siguiente:<br>1 - 3 - 2  
 +
  
 
<br>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]:<br>1 - 2 - 3  
 
<br>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]:<br>1 - 2 - 3  
 +
  
<br>El mismo procedimiento se aplicará a la otra sublista. Al finalizar y unir todas las sublistas queda la lista inicial ordenada en forma ascendente.<br>1 - 2 - 3 - 4 - 5 - 6 - 7
+
<br>El mismo procedimiento se aplicará a la otra sublista. Al finalizar y unir todas las sublistas queda la lista inicial ordenada en forma ascendente.<br>1 - 2 - 3 - 4 - 5 - 6 - 7<br>
 +
  
 
+
== <br>Referencias ==
 
 
== <br> ==
 
 
 
== Referencias ==
 
  
 
*[[Quick Sort|Quick Sort]]&nbsp;
 
*[[Quick Sort|Quick Sort]]&nbsp;
 +
 
*[[Ordenamiento rápido, Implementación y descripción|Ordenamiento rápido, Implementación y descripción]]
 
*[[Ordenamiento rápido, Implementación y descripción|Ordenamiento rápido, Implementación y descripción]]
 +
 
*[[QuickSort C Code|QuickSort C Code]]
 
*[[QuickSort C Code|QuickSort C Code]]
 +
 
*[[Wikipedia|Wikipedia]]
 
*[[Wikipedia|Wikipedia]]
  
 
<br>
 
<br>
 
   
 
   
 
 
 
 
 
  
 
[[Category:Algoritmos]]
 
[[Category:Algoritmos]]

Revisión del 09:01 5 abr 2011

Ordenamiento por Quicksort
Información sobre la plantilla
260px


El ordenamiento rápido, quicksort en inglés: Es un algoritmo 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.




Descripción del algoritmo

El algoritmo consta de los siguientes pasos:


  1. Elegir un elemento de la lista de elementos a ordenar, al que llamaremos pivote.
  1. Resituar los demás 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 implementación deseada. En este momento, el pivote ocupa exactamente el lugar que le corresponderá en la lista ordenada.
  1. La lista queda separada en dos sublistas, una formada por los elementos a la izquierda del pivote, y otra por los elementos a su derecha.
  1. 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.



Eficiencia del algoritmo

La eficiencia del algoritmo depende de la posición en la que termine el pivote elegido.
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).
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). Y no es extraño, pues, que la mayoría de optimizaciones que se aplican al algoritmo se centren en la elección del pivote.



Demostración

Suponiendo que el número total de elementos a ordenar es potencia de dos, es decir, n = 2k. De aquí podemos ver que k = log2(n), donde k es el número de divisiones que realizará el algoritmo.


En la primera fase del algoritmo habrán n comparaciones, en la segunda fase el algoritmo creará dos sublistas aproximadamente de tamaño n/2. El número total de comparaciones de estas dos sublistas es: 2(n/2) = n. En la tercera fase el algoritmo procesará 4 sublistas más, por tanto el número total de comparaciones en esta fase es 4(n/4) = n.


En conclusión, el número total de comparaciones que hace el algoritmo es:


n + n + n + ..... + n = kn, donde k = log2(n), por tanto el tiempo de ejecución del algoritmo en el mejor caso es O(n.log2n)



Optimización del algoritmo

Cabe destacar que de usarse en su versión recursiva las siguientes optimizaciones y sus desventajas no se ven vistas en el tiempo de ejecución del mismo manteniéndose, así el tiempo de ejecución planteado en un principio.



Técnicas de elección del pivote

El algoritmo básico del método Quicksort consiste en tomar cualquier elemento de la lista al cual denominaremos como pivote, dependiendo de la partición en que se elija, el algoritmo será más o menos eficiente.
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.
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 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.



Técnicas de reposicionamiento

Una idea preliminar para ubicar el pivote en su posición 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 pueda aplicarse la recursividad.


Existe, no obstante, un procedimiento mucho más efectivo. Se utilizan dos índices: i, al que llamaremos índice izquierdo, y j, al que llamaremos índice derecho. El algoritmo es el siguiente:


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).
Cuando lista[i] sea mayor que el pivote y lista[j] sea menor, se intercambian los elementos en esas posiciones.


Repetir esto hasta que se crucen los índices.
El punto en que se cruzan los índices es la posición adecuada para colocar el pivote, porque sabemos que a un lado los elementos son todos menores y al otro son todos mayores (o habrían sido intercambiados).



Parámetros: 

  1. Se debe llamar a la función Quicksort desde donde quiera ejecutarse
  1. Ésta llamará a colocar pivote para encontrar el valor del mismo
  1. Se ejecutará el algoritmo Quicksort de forma recursiva a ambos lados del pivote


int colocar(int *v, int b, int t)
{
int i;
int pivote, valor_pivote;
int temp;

pivote = b;
valor_pivote = v[pivote];
for (i=b+1; i<=t; i++){
if (v[i] < valor_pivote){
pivote++;
temp=v[i];
v[i]=v[pivote];
v[pivote]=temp;

}
}
temp=v[b];
v[b]=v[pivote];
v[pivote]=temp;
return pivote;
}
void Quicksort(int* v, int b, int t)
{
int pivote;
if(b < t){
pivote=colocar(v, b, t);
Quicksort(v, b, pivote-1);
Quicksort(v, pivote+1, t);
}
}


Nota: Los tres parámetros de la llamada inicial a Quicksort serán array[0], 0, numero_elementos -1, es decir, si es un array de 6 elementos array[0], 0, 5






Implementación del Pseudocódigo

function quicksort(array)
var list, less, greater
if length(array) ≤ 1
return array
seleccionar y eliminar un valor pivote pivot en el array
for each x in array
if x < pivot then añadir x a less
else añadir x a greater
return concadenar(quicksort(less), pivot, quicksort(greater))



Ejemplo

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



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] (pasos 16-18):
1 - 3 - 2 - 4 - 7 - 5 - 6
p



Aplicamos recursivamente a la sublista 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 sublista. Al finalizar y unir todas las sublistas queda la lista inicial ordenada en forma ascendente.
1 - 2 - 3 - 4 - 5 - 6 - 7



Referencias