Saltar al contenido
EjemplosEnglishEspacio →

Ordenamiento por mezcla

Parte el arreglo en mitades, ordena cada una con recursión y las mezcla.

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

Ejecuta, modifica y depura este ejemplo en el navegador.

Lo que aprenderás

OrdenarPorMezcla se llama a sí mismo con cada mitad hasta llegar a tramos de un elemento, y Mezclar une dos tramos ordenados tomando siempre el menor de los dos frentes. Se parte en mitades unas log n veces y cada nivel mezcla n elementos: O(n log n) siempre, a cambio de un arreglo temporal de tamaño n. Los arreglos se pasan por referencia, así que todos los subprocesos trabajan sobre el mismo arreglo.

Código

merge-sort.psc · 74 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// Une dos tramos ya ordenados: datos[izquierda..medio] y datos[medio+1..derecha]SubProceso Mezclar(datos, temporal, izquierda, medio, derecha)    Definir i, j, k Como Entero    i <- izquierda    j <- medio + 1    k <- izquierda    // Tomamos siempre el menor de los dos frentes    Mientras i <= medio Y j <= derecha Hacer        // Con <= los iguales conservan su orden: por eso es estable        Si datos[i] <= datos[j] Entonces            temporal[k] <- datos[i]            i <- i + 1        SiNo            temporal[k] <- datos[j]            j <- j + 1        FinSi        k <- k + 1    FinMientras    // Copiamos lo que haya sobrado de cualquiera de las dos mitades    Mientras i <= medio Hacer        temporal[k] <- datos[i]        i <- i + 1        k <- k + 1    FinMientras    Mientras j <= derecha Hacer        temporal[k] <- datos[j]        j <- j + 1        k <- k + 1    FinMientras    // Devolvemos el tramo mezclado al arreglo original    Para k <- izquierda Hasta derecha Hacer        datos[k] <- temporal[k]    FinParaFinSubProceso// Los arreglos se pasan por referencia: el subproceso ordena el arreglo del algoritmoSubProceso OrdenarPorMezcla(datos, temporal, izquierda, derecha)    Definir medio Como Entero    // Un tramo de un solo elemento ya está ordenado: ahí termina la recursión    Si izquierda < derecha Entonces        medio <- Trunc((izquierda + derecha) / 2)        OrdenarPorMezcla(datos, temporal, izquierda, medio)        OrdenarPorMezcla(datos, temporal, medio + 1, derecha)        Mezclar(datos, temporal, izquierda, medio, derecha)    FinSiFinSubProcesoAlgoritmo OrdenamientoMezcla    Definir datos, temporal, n, i Como Entero    Escribir "¿Cuántos números quieres ordenar? (1 a 512)"    Leer n    // temporal es la memoria extra que necesita la mezcla    Dimension datos[n], temporal[n]    Para i <- 1 Hasta n Hacer        datos[i] <- Aleatorio(1, 99)    FinPara    MostrarDatos("Antes:   ", datos, n)    OrdenarPorMezcla(datos, temporal, 1, n)    MostrarDatos("Después: ", datos, n)FinAlgoritmo

Diagrama de flujo

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

Algoritmo OrdenamientoMezcla
Algoritmo OrdenamientoMezclaAlgoritmo OrdenamientoMezclaAlgoritmo OrdenamientoMezclaDefinir datos, temporal, n, i Como EnteroDefinir datos, temporal, n, iComo EnteroEscribir "¿Cuántos números quieres ordenar? (1 a 512)"Escribir "¿Cuántos númerosquieres ordenar? (1 a 512)"Leer nLeer nDimension datos[n], temporal[n]Dimension datos[n],temporal[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)OrdenarPorMezcla(datos, temporal, 1, n)OrdenarPorMezcla(datos,temporal, 1, n)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 Mezclar
SubProceso MezclarSíNoSíNoSíNoSíNoSubProceso Mezclar(datos, temporal, izquierda, medio, derecha)SubProceso Mezclar(datos,temporal, izquierda, medio,…Definir i, j, k Como EnteroDefinir i, j, k Como Enteroi <- izquierdai <- izquierdaj <- medio + 1j <- medio + 1k <- izquierdak <- izquierdaMientras i <= medio Y j <= derecha Haceri <= medio Y j <=derechaSi datos[i] <= datos[j] Entoncesdatos[i] <= datos[j]temporal[k] <- datos[i]temporal[k] <- datos[i]i <- i + 1i <- i + 1temporal[k] <- datos[j]temporal[k] <- datos[j]j <- j + 1j <- j + 1k <- k + 1k <- k + 1Mientras i <= medio Haceri <= mediotemporal[k] <- datos[i]temporal[k] <- datos[i]i <- i + 1i <- i + 1k <- k + 1k <- k + 1Mientras j <= derecha Hacerj <= derechatemporal[k] <- datos[j]temporal[k] <- datos[j]j <- j + 1j <- j + 1k <- k + 1k <- k + 1Para k <- izquierda Hasta derecha HacerPara k <- izquierda Hastaderechadatos[k] <- temporal[k]datos[k] <- temporal[k]FinSubProcesoFinSubProceso
SubProceso OrdenarPorMezcla
SubProceso OrdenarPorMezclaSíNoSubProceso OrdenarPorMezcla(datos, temporal, izquierda, derecha)SubProceso OrdenarPorMezcla(datos,temporal, izquierda, derecha)Definir medio Como EnteroDefinir medio Como EnteroSi izquierda < derecha Entoncesizquierda < derechamedio <- Trunc((izquierda + derecha) / 2)medio <- Trunc((izquierda +derecha) / 2)OrdenarPorMezcla(datos, temporal, izquierda, medio)OrdenarPorMezcla(datos,temporal, izquierda, medio)OrdenarPorMezcla(datos, temporal, medio + 1, derecha)OrdenarPorMezcla(datos,temporal, medio + 1,derecha)Mezclar(datos, temporal, izquierda, medio, derecha)Mezclar(datos, temporal,izquierda, medio, derecha)FinSubProcesoFinSubProceso

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:   42 60 96 80 54 87 85 17 84 18 5 79 Después: 5 17 18 42 54 60 79 80 84 85 87 96 

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(n)

Características:Estable

Desafío

Muestra en pantalla cada tramo que se mezcla, con su izquierda y su derecha.

Ver pista

Agrega un Escribir al principio de Mezclar; prueba con n chico para que no sean demasiadas líneas.

Abrir en Codoritmo