Quicksort es un algoritmo de ordenación que se utiliza para ordenar los elementos de un arreglo. Fue creado por Tony Hoare en 1959 y sigue siendo uno de los algoritmos de referencia para ordenar por comparación. Su idea básica es dividir y conquistar: selecciona un elemento llamado pivote, reordena (particiona) el arreglo para que los elementos menores queden a un lado y los mayores al otro, y luego aplica recursivamente el mismo procedimiento a las subpartes.
Cómo funciona (concepto general)
Los pasos generales de Quicksort son:
- Elegir un pivote: puede ser el primer elemento, el último, un elemento aleatorio o una mediana aproximada.
- Particionar: reorganizar el arreglo de modo que los valores ≤ pivote queden a la izquierda y los ≥ pivote a la derecha (la definición exacta depende del esquema de partición).
- Recursión: aplicar Quicksort a la subparte izquierda y a la subparte derecha hasta que las subpartes tengan tamaño 0 o 1.
Esquemas de partición
Los dos esquemas más conocidos son:
- Partición de Hoare: utiliza dos índices que se mueven desde los extremos hacia el centro; suele ser más eficiente y realiza menos intercambios.
- Partición de Lomuto: más simple de implementar, usa un índice para separar la zona de elementos menores y realiza más intercambios en promedio.
Además hay variantes de partición en tres vías (Dutch National Flag) que son útiles cuando hay muchos elementos iguales: separan en menor, igual y mayor al pivote.
Complejidad y características
- Complejidad promedio: O(n log n).
- Peor caso: O(n²), ocurre cuando la partición es muy desequilibrada (por ejemplo, pivote siempre mínimo o máximo en una lista ya ordenada y elección pobre del pivote).
- Mejor caso: O(n log n), cuando las particiones son equilibradas.
- Espacio: generalmente O(log n) adicional por la pila de recursión en la versión in-place; la implementación iterativa o con eliminación de recursión de cola puede reducir la profundidad práctica.
- No es estable en su forma estándar (el orden relativo de claves iguales no se preserva).
- In-place: sí, las versiones típicas realizan la ordenación sin necesitar una estructura auxiliar proporcional a n.
Optimización y variantes prácticas
- Elección aleatoria del pivote: reduce la probabilidad del peor caso en entradas adversas.
- Mediana de tres: elegir como pivote la mediana entre el primero, el último y el central mejora las particiones en datos parcialmente ordenados.
- Umbral para inserción: cuando las subpartes son pequeñas (p. ej. ≤ 10), cambiar a insertion sort suele ser más eficiente.
- Introsort: híbrido que empieza con Quicksort y cambia a Heapsort si la recursión se vuelve demasiado profunda, garantizando O(n log n) en el peor caso.
- Partición en tres vías: mejora el rendimiento cuando hay muchas claves repetidas.
- Paralelización: las subpartes independientes se pueden ordenar en paralelo para aprovechar arquitecturas multicore.
Ejemplo paso a paso (resumen)
Sea el arreglo [3, 7, 8, 5, 2, 1, 9, 5, 4] y supongamos que elegimos como pivote el último elemento (4) con partición de Lomuto:
- Partición: mover elementos menores que 4 al inicio → resultado parcial: [3, 2, 1, 4, 7, 9, 5, 5, 8] (4 queda en su posición final).
- Aplicar recursión a izquierda [3,2,1] y derecha [7,9,5,5,8] hasta que todas las sublistas estén ordenadas.
- Orden final: [1,2,3,4,5,5,7,8,9].
Implementación (pseudocódigo simplificado)
function quicksort(A, lo, hi) if lo < hi p = partition(A, lo, hi) // según Lomuto o Hoare quicksort(A, lo, p - 1) quicksort(A, p + 1, hi)
La función partition varía según el esquema escogido. En Lomuto se devuelve la posición final del pivote; en Hoare se devuelve un índice que divide las subpartes.
Cuándo usar Quicksort
- Excelente rendimiento promedio y práctica para arreglos en memoria.
- Buena elección cuando se desea un algoritmo in-place y rápido en la mayoría de casos.
- Si se requiere estabilidad o garantizado O(n log n) en el peor caso, conviene considerar mergesort (estable, O(n log n) pero requiere espacio adicional) o usar introsort.
Resumen: Quicksort es un algoritmo de ordenación por particiones eficiente y versátil en la práctica. Su rendimiento depende mucho de la elección del pivote y del esquema de partición, y existen muchas mejoras y variantes que lo hacen robusto y competitivo en una gran variedad de aplicaciones.

