Saltar al contenido
EjemplosEnglishEspacio →

Ordenamiento por montículo

Organiza el arreglo como un montículo y saca el mayor una y otra vez.

Nivel
Avanzado
Conceptos:
Entrada y salida
Arreglos
SubProcesos
Mientras
Para
Si
Lógicos
Azar
Abrir en Codoritmo

Ejecuta, modifica y depura este ejemplo en el navegador.

Lo que aprenderás

Un montículo es un árbol guardado en el arreglo: los hijos de la posición k están en 2k y 2k + 1, y cada padre es mayor que sus hijos, así que el mayor queda en la posición 1. Se lo cambia con el último, se achica el montículo y Hundir lo repara en log n pasos. Cuesta O(n log n) siempre y no usa memoria extra.

Código

heap-sort.psc · 63 líneas
// 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// En un montículo, el padre de la posición k está en Trunc(k / 2)// y sus hijos en 2k y 2k + 1. Cada padre es mayor o igual que sus hijos.// Hundir baja el valor de la posición raiz hasta que vuelve a cumplirse.SubProceso Hundir(datos, raiz, tamanio)    Definir actual, hijo, aux Como Entero    Definir listo Como Logico    actual <- raiz    listo <- Falso    Mientras (NO listo) Y 2 * actual <= tamanio Hacer        // Elegimos el mayor de los dos hijos        hijo <- 2 * actual        Si hijo + 1 <= tamanio Entonces            Si datos[hijo + 1] > datos[hijo] Entonces                hijo <- hijo + 1            FinSi        FinSi        Si datos[hijo] > datos[actual] Entonces            aux <- datos[actual]            datos[actual] <- datos[hijo]            datos[hijo] <- aux            actual <- hijo        SiNo            listo <- Verdadero        FinSi    FinMientrasFinSubProcesoAlgoritmo OrdenamientoMonticulo    Definir datos, n, i, ultimo, aux 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)    // 1) Armamos el montículo, desde el último padre hasta la raíz    Para i <- Trunc(n / 2) Hasta 1 Con Paso -1 Hacer        Hundir(datos, i, n)    FinPara    // 2) El mayor está en la raíz: lo llevamos al final y reparamos el resto    Para ultimo <- n Hasta 2 Con Paso -1 Hacer        aux <- datos[1]        datos[1] <- datos[ultimo]        datos[ultimo] <- aux        Hundir(datos, 1, ultimo - 1)    FinPara    MostrarDatos("Después: ", datos, n)FinAlgoritmo

Diagrama de flujo

Cada bloque del diagrama corresponde a una instrucción del código.

Algoritmo OrdenamientoMonticulo
Algoritmo OrdenamientoMonticuloAlgoritmo OrdenamientoMonticuloAlgoritmo OrdenamientoMonticuloDefinir datos, n, i, ultimo, aux Como EnteroDefinir datos, n, i, ultimo,aux Como EnteroEscribir "¿Cuántos números quieres ordenar? (1 a 512)"Escribir "¿Cuántos númerosquieres ordenar? (1 a 512)"Leer nLeer nDimension datos[n]Dimension datos[n]Para i <- 1 Hasta n HacerPara i <- 1 Hasta ndatos[i] <- Aleatorio(1, 99)datos[i] <- Aleatorio(1, 99)MostrarDatos("Antes: ", datos, n)MostrarDatos("Antes: ",datos, n)Para i <- Trunc(n / 2) Hasta 1 Con Paso -1 HacerPara i <- Trunc(n / 2) Hasta1 Con Paso -1Hundir(datos, i, n)Hundir(datos, i, n)Para ultimo <- n Hasta 2 Con Paso -1 HacerPara ultimo <- n Hasta 2 ConPaso -1aux <- datos[1]aux <- datos[1]datos[1] <- datos[ultimo]datos[1] <- datos[ultimo]datos[ultimo] <- auxdatos[ultimo] <- auxHundir(datos, 1, ultimo - 1)Hundir(datos, 1, ultimo - 1)MostrarDatos("Después: ", datos, n)MostrarDatos("Después: ",datos, n)FinAlgoritmoFinAlgoritmo
SubProceso MostrarDatos
SubProceso MostrarDatosSíNoSubProceso MostrarDatos(titulo, datos, n)SubProceso MostrarDatos(titulo,datos, n)Definir i Como EnteroDefinir i Como EnteroSi n <= 30 Entoncesn <= 30Escribir Sin Saltar tituloEscribir Sin Saltar tituloPara i <- 1 Hasta n HacerPara i <- 1 Hasta nEscribir Sin Saltar datos[i], " "Escribir Sin Saltar datos[i]," "Escribir ""Escribir ""Escribir titulo, n, " números (el primero es ", datos[1], " y el último ", datos[n], ")"Escribir titulo, n, " números(el primero es ", datos[1], "y el último ", datos[n], ")"FinSubProcesoFinSubProceso
SubProceso Hundir
SubProceso HundirSíNoSíNoSíNoSíNoSubProceso Hundir(datos, raiz, tamanio)SubProceso Hundir(datos, raiz,tamanio)Definir actual, hijo, aux Como EnteroDefinir actual, hijo, aux ComoEnteroDefinir listo Como LogicoDefinir listo Como Logicoactual <- raizactual <- raizlisto <- Falsolisto <- FalsoMientras (NO listo) Y 2 * actual <= tamanio Hacer(NO listo) Y 2 *actual <= tamaniohijo <- 2 * actualhijo <- 2 * actualSi hijo + 1 <= tamanio Entonceshijo + 1 <= tamanioSi datos[hijo + 1] > datos[hijo] Entoncesdatos[hijo + 1] >datos[hijo]hijo <- hijo + 1hijo <- hijo + 1Si datos[hijo] > datos[actual] Entoncesdatos[hijo] >datos[actual]aux <- datos[actual]aux <- datos[actual]datos[actual] <- datos[hijo]datos[actual] <- datos[hijo]datos[hijo] <- auxdatos[hijo] <- auxactual <- hijoactual <- hijolisto <- Verdaderolisto <- VerdaderoFinSubProcesoFinSubProceso

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:   63 59 13 90 53 24 26 22 61 5 81 21 Después: 5 13 21 22 24 26 53 59 61 63 81 90 

Complejidad

Cuánto trabajo y memoria necesita según la cantidad de datos (n).

Complejidad
CasoCosto
MejorO(n log n)
PromedioO(n log n)
PeorO(n log n)
MemoriaO(1)

Características:No estableEn el lugar

Desafío

Muestra el arreglo justo después de armar el montículo y comprueba que datos[1] es el mayor.

Ver pista

Llama a MostrarDatos entre los dos Para del algoritmo principal.

Abrir en Codoritmo
  • Ordenamiento Shell

    Una inserción entre elementos lejanos, con un salto que se achica en cada pasada.

    Avanzado
  • Ordenamiento burbuja

    Ordena números al azar intercambiando vecinos, y se detiene apenas quedan ordenados.

    Intermedio
  • Ordenamiento por inserción

    Inserta cada número entre los ya ordenados, como al acomodar cartas en la mano.

    Intermedio