Ordenamiento rápido (Quicksort)
Elige un pivote, separa los menores de los mayores y ordena cada lado con recursión.
- Nivel
- Avanzado
- Conceptos:
- Entrada y salida
- Arreglos
- SubProcesos
- Funciones
- Recursión
- Repetir
- Si
- Azar
Ejecuta, modifica y depura este ejemplo en el navegador.
Lo que aprenderás
Particionar usa el método de Hoare: dos índices avanzan desde los extremos hacia el centro y se intercambian cuando cada uno encuentra un valor del lado equivocado del pivote. Después cada parte se ordena con la misma idea. Si el pivote parte el arreglo más o menos por la mitad cuesta O(n log n); si siempre cae en un extremo, O(n²). No necesita arreglo extra, solo la pila de llamadas (O(log n)).
Código
// Muestra el arreglo completo solo si es corto (30 o menos)SubProceso MostrarDatos(titulo, datos, n) Definir i Como Entero Si n <= 30 Entonces Escribir Sin Saltar titulo Para i <- 1 Hasta n Hacer Escribir Sin Saltar datos[i], " " FinPara Escribir "" SiNo Escribir titulo, n, " números (el primero es ", datos[1], " y el último ", datos[n], ")" FinSiFinSubProceso// Partición de Hoare: deja a la izquierda los valores <= pivote y a la derecha// los >= pivote, y devuelve dónde termina la parte izquierda.Funcion corte <- Particionar(datos, izquierda, derecha) Definir corte, pivote, i, j, aux Como Entero // Usamos el elemento del medio como pivote pivote <- datos[Trunc((izquierda + derecha) / 2)] i <- izquierda - 1 j <- derecha + 1 Repetir // i avanza hasta encontrar uno que no debería estar a la izquierda Repetir i <- i + 1 Hasta Que datos[i] >= pivote // j retrocede hasta encontrar uno que no debería estar a la derecha Repetir j <- j - 1 Hasta Que datos[j] <= pivote // Si no se cruzaron, los intercambiamos y seguimos Si i < j Entonces aux <- datos[i] datos[i] <- datos[j] datos[j] <- aux FinSi Hasta Que i >= j corte <- jFinFuncionSubProceso OrdenarRapido(datos, izquierda, derecha) Definir corte Como Entero Si izquierda < derecha Entonces corte <- Particionar(datos, izquierda, derecha) // Cada lado se ordena por separado, con la misma idea OrdenarRapido(datos, izquierda, corte) OrdenarRapido(datos, corte + 1, derecha) FinSiFinSubProcesoAlgoritmo Quicksort Definir datos, n, i Como Entero Escribir "¿Cuántos números quieres ordenar? (1 a 512)" Leer n Dimension datos[n] Para i <- 1 Hasta n Hacer datos[i] <- Aleatorio(1, 99) FinPara MostrarDatos("Antes: ", datos, n) OrdenarRapido(datos, 1, n) MostrarDatos("Después: ", datos, n)FinAlgoritmoDiagrama de flujo
Cada bloque del diagrama corresponde a una instrucción del código.
Ejemplo de ejecución
Esto muestra el programa al ejecutarlo. Las respuestas escritas por el usuario aparecen resaltadas.
¿Cuántos números quieres ordenar? (1 a 512)Respuesta del usuario: 12Antes: 57 95 53 48 81 13 78 10 53 4 56 3 Después: 3 4 10 13 48 53 53 56 57 78 81 95
Complejidad
Cuánto trabajo y memoria necesita según la cantidad de datos (n).
| Caso | Costo |
|---|---|
| Mejor | O(n log n) |
| Promedio | O(n log n) |
| Peor | O(n²) |
| Memoria | O(log n) |
Características:No estableEn el lugar
Desafío
Usa como pivote un elemento al azar del tramo en lugar del del medio.
Ver pista
Aleatorio(izquierda, derecha) da una posición del tramo; guarda datos[esa posición] en pivote.
Ejemplos relacionados
Búsqueda lineal contra binaria
Cuenta las comparaciones que necesita cada búsqueda en la misma lista ordenada.
IntermedioOrdenamiento Shell
Una inserción entre elementos lejanos, con un salto que se achica en cada pasada.
AvanzadoOrdenamiento burbuja
Ordena números al azar intercambiando vecinos, y se detiene apenas quedan ordenados.
Intermedio