Mezcla Directa (MERGE) 7.3 Mezcla
Directa
(MERGE)
a) Descripcion Este metodo de llama mezcla porque combina dos o mas secuencias en una sola secuencia ordenada por medio de la seleccion repetida de los componenetes accesibles en ese momento. Un arreglo individual puede usarse en lugar de dos secuencias si se considera como de doble extremo. En este caso se tomaran elementos de los dos extremos del arreglo para hacer la mezcla. El destino de los elementos combinados se cambia despues de que cada par ha sido ordenado para llenar uniformemente las dos secuencias que son el destino. Despues de cada pasada los dos extremos del arreglo intercambian de papel, la fuente se convierte en el nuevo destino y viceversa. b) Algoritmo 1.Inicio 2.Dividir la secuencia A en dos mitades denomindas B y C. 3.Mezclar B y C combinando cada elemento en pares ordenados. 4.- Llamar A a la secuencia mezclada y repetir los pasos 1 y 2, esta vez combinando los pares en cuadriples ordenados. 5.- Repetir los pasos anteriores duplicando cada vez la longitud de las secuencias combinadas hasta que quede ordenada la secuencia original. 6.Fin del Algoritmo. c)
d) Fuente A={29,17,31,25, 1 2
Diagrama
de
Corrida
de
, 3
Flujo
, 4
, 5
,} 6
7
Escritorio Destino N=4 8
UP=TRUE P=1 do H=1 M=N,M=4 Si I=1 J=N,J=4 K=N+1,K=4+1= L=2*N,L=2*4= do Si Q=P M=M-Q Si R=P,R= M=M-R,M=3-1=
1
UP=TRUE,TRUE=TRUE
(Si)
5 8
M>=P,4>=1
M>=P,3>=1
2 (Si)
(Si) 1 2
Mientras Q!=0 1!=0 Si 29<25> A[K]=A[J],A[5]=A[4]= K=K+H,K=5+1= J=J-1,J=4-1= R=R-1,R=1-1=
and
R!=0
and
-----------1!=0
23 6 3 0
-------> Mientras 1!=0 Mientras Mientras A[K]=A[I],A[6]=A[1],A[6]=29 K=K+1,K=6+1= I=I+1,I=1+1= Q=Q-1.Q=1-1= Mientras H=-H,H=-1 T=K,T=7 K=L,K=8 L=T,L=7
|A| (Si) A[I]
|A| (Si) R>0,0>0
and
0!=0 (No)
Q>0,1>0
0>0
(No)
(No)
(Sale) (Sale) (Si) 7 2 0 (Sale) der->izq
7.1.2 Mezcla Natural Ordenación por el método de mezcla equilibrada El método de ordenación por mezcla equilibrada, conocido como natural, es una optimization del metodo de mezcla directa.
tambien
La idea central de este algoritmo consiste en realizar las particiones tomando secuencias ordenadas de máxima longitud en lugar de secuencias de tamaño fijo previamente determinadas. Luego se realiza la fusion de las secuencias ordenadas, en alternada, sobre dos archivos. Aplicando estas acciones en forma repetida se logrará el archivo original quede ordenado. Para la realization de este proceso de ordenación se necesitaran cuatro archivos. El archivo original F y tres archivos auxiliares a los que se denominara F1, F2 y F3. De estos archivos, dos serán considerados de entrada y dos de salida; esto, de manera alternada, con el objeto de realizar la fusion-partición. El proceso termina cuando en la realización de una fusion-partición el segundo archivo quede vacío. Supongamos que se desea ordenar las claves del archivo F utilizando el método mezcla equilibrada. 09 75 14 68 29 17 31 25 04 05 13 18 F: 72 46 61 Los pasos que se realizan son:
PARTICIÓN F2: F3:
09 14
68'
F:
09
14
75' 17 68
INICIAL
29' 25' 46 31' 04 05 13 18 72' PRIMERA FUSION-PARTICION 75' 04 05 13 18 25 46
61'
61
72
'
F1:
17
29
31'
SEGUNDA FUSION-PARTICION 14 17 29 31 68 75' F1: 09 F3: 04 05 13 18 25 46 61 72' TERCERA FUSION-PARTICION 04 05 09 13 14 17 18 25 29 31 46 61 F: 68 72 75 Observe que al realizar la tercera fusion-partición el segundo archivo queda vacío; por lo tanto, se puede afirmar que el archivo ya se encuentra ordenado. A continuación se presenta la description formal del algoritmo de mezcla equilibrada.
Mezcla_equilibrada
(F,
F1,
F2,
El algoritmo ordena los elementos del archivo F por el metodo de equilibrada. Utiliza tres archivos auxiliares F1, F2 y F3 BAND variable de tipo booleano 1. Llamar al algoritmo Particion inicial con F, F2 al algoritmo Particion fusion con F1, 2. Llamar F3, F
F3)
mezcla es una y y
F3 F1
3. Hacer 4. Mientras
BAND <- FALSO ((F1 ≠ VACIO)
o
(F3
≠VACIO))
4.1. Si (BAND
=
Repetir
VERDADERO) entonces
Llamar al algoritmo Particion_fusion con F2, F3, F
y
F1
Hacer
BAND <- FALSO si
no
Llamar al algoritmo Particion_fusion con F, F1,F2 y
F3
Hacer condicional
BAND <- VERDADERO del paso 4.1
4.2. Fin del 5. Fin del ciclo del paso 4 El algoritmo requiere para su funcionamiento de dos algoritmos auxiliares, Particion_inicial yParticion_fusion, los cuales se presentan a continuation. Particion_inicial (F, F2, F3)El algoritmo produce la particion inicial del archivo F en dos archivos auxiliares, F2 y F3 AUX y R son variables de tipo entero. BAND es una variable de tipo booleano 1. Abrir el archivo F para lectura. 2. Abrir los archivos F2 y F3 para escritura. 3. Leer R de F. 4. Escribir R en F2. BAND <- VERDADERO y AUX <- R 5. Hacer 6. Mientras (no sea el fin de archivo de F) Repetir Leer R de F 6.1 Si (R a AUX) entonces
Hacer 6.1.1 Si (BAND
AUX =
<-R VERDADERO) entonces
Escribir R
en
si 6.1.2. Fin
del
condicional
no
Escribir R en F3 del paso 6.1.1
si
6.1.3. Si (BAND
F2
Hacer = VERDADERO) Escribir R Hacer BAND
no
AUX <- R entonces
en F3 <- FALSO si
no
Escribir R en F2 Hacer BAND <- VERDADERO 6.1.4. Fin del condicional del paso 6.1.3 6.2. Fin del condicional del paso 6.1 7. Fin del ciclo del paso 6 8. Cerrar los archivos F, F2 y F3
Particion_fusion
(FA, FB, FC, FD)
El algoritmo produce la particion y la fusion de los archivos FA y FB, en los archivos FC y FD R1, R2 y AUX son variables de tipo entero. BANl, BAN2 y BAN3 son variables de tipo booleano 1. Abrir los archivos FA y FBpara lectura. 2. Abrir los archivos FC y FD para escritura. 3. Hacer BAN1 <- VERDADERO, BAN2 <- VERDADERO, BAN3 <- VERDADERO y AUX <- -32 768 {AUX se inicializa con un valor negativo alto} 4. Mientras ((no sea el fin de archivo de FA) o (BANl = FALSO)) y ((no sea el fin de archivo de FB) o ((BAN2 = FALSO)) Repetir 4.1. Si (BAN1 = VERDADERO) entonces Leer R1 de FA Hacer BAN1 <- FALSO 4.2. Fin del condicional del paso 4.1 4.3 Si (BAN2 = VERDADERO) entonces Leer R2 de FB Hacer BAN2 <- FALSO 4.4. Fin del condicional del paso 4.3 4.5. Si (R1 < R2) entonces 4.5.1. Si entonces (R1 ≥ AUX) 4.5.1.1. Sí(BAN3 = VERDADERO) entonces
Escribir R1
en
FC si no
condicional AUX <-
Escribir R1 en FD 4.5.1.2. Fin del paso 4.5.1.1 Hacer BAN1 <- VERDADERO y
del
R1 si
4.5.1.3.Si
no
(BAN3
=
VERDADERO) entonces
Escribir R2 en FC Hacer
BAN3 <- FALSO si
no
Escribir R2 en FD Hacer condicional
del
paso
BAN3 <- VERDADERO 4.5.1.4 Fin del 4.5.1.3
Hacer
VERDADERO
y
BAN2
4.5.3 Si
no
(R2
≥
AUX)
entonces 4.5.3.1. Si (BAN3
=
VERDADERO) entonces
Escribir R2 en FC si
no
Escribir R2 en FD 4.5.3.2.
Fin
del
condicional
del
BAN2 <- VERDADERO
paso
y
4.5.3.1 Hacer AUX <- R2 Si
Si (BAN3
no
4.5.3.3. VERDADERO)
=
entonces Escribir R1 en Hacer
BAN3 <- FALSO
si Escribir Hacer
Fin
del
BAN1 <- VERDADERO
5. Fin 6. Si (BAN1
el
del
fin
FC
no R1
en
FD
BAN3 <- VERDADERO 4.5.3.4. condicional del paso 4.5.3.3 Hacer y AUX <- -32 768 4.5.4. Fin del condicional del paso 4.5.3 4.6. Fin del condicional del paso 4.5 ciclo del paso 4 = FALSO) entonces (BAN3 = VERDADERO) 6.1. Si entonces Escribir R1 en FC 6.1.1. Mientras (no sea de archivo de FA) Repetir
Leer R1 FA Escribir FC 6.1.2. Fin del ciclo del 6.1.1
de R1 en
paso
si
el
fin
de
archivo
no
Escribir R1 en FD 6.1.3. Mientras (no sea de FA) Repetir Leer R1
de FA Escribir R1
en
FD 6.1.4.Fin del ciclo del
paso 7. Fin 8. Si (BAN2
del
6.2. Fin del condicional =
condicional del 8.1
6.1.3 del paso 6.1 paso 6 FALSO) entonces Sí'(BAN3=VERDADERO) entonces
Escribir R2 en FC 8.1.1 Mientras (no sea el fin de archivo de FB)
Repetir
8.1.2 Fin del
Leer R2 de FB Escribir R2 en FC ciclo del paso 8.1.1 si
no
Escribir R1 en FD 8.1.3. Mientras (no sea el fin de archivo de FB)
Repetir Leer
R2
de
FB
Escribir R2 en FD 8.1.4. Fin del ciclo del paso 8.1.3 8.2. Fin del condicional del paso 8.1 9. Fin del condicional del paso 8 10.Cerrar los archivos FA, FB, FC y FD Ejemplo en lenjuage C void mezclaEquilibrada(int archf, int archf1, int archf2, int archf3){ int archivo_vacio=ARCHIVO_NINGUNO; boolean band; particionInicial(archf, archf2, archf3); //imprimir("después de partición inicial"); band = true; do{ if(band){ particionFusion(archf2, archf3, archf, archf1);
//imprimir("después de partición fusión con band=true"); band=false; }else{ particionFusion(archf, archf1, archf2, archf3); //imprimir("después de partición fusión con band=false"); band=true; } abrirL(archf1); archivo_vacio=ARCHIVO_F1; cerrar(archf1);
if(fin(archf1))
el:
if(archivo_vacio==ARCHIVO_NINGUNO){ abrirL(archf3); if(fin(archf3)) archivo_vacio=ARCHIVO_F3; cerrar(archf3); } }while(archivo_vacio==ARCHIVO_NINGUNO); imprimir("al final"); printf("el archivo que está vacío es: %d\nEl listado final está en %d\n", archivo_vacio, archivo_vacio-1);
} void particionInicial(int
/*
Si
band==true, *
archf,
int
registro el último sino,
archf2,
registro fue
int
aux, se escribió en
boolean
archf3){ r; en f2, f3 */ band;
abrirL(archf); abrirE(archf2); abrirE(archf3); if(!leer(archf, printf("Archivo
&r)){ vacío\n"); cerrar(archf); cerrar(archf2); cerrar(archf3); exit(0); } escribir(archf2,r); band=true; aux=r; while(!fin(archf)){ leer(archf, &r);
if(r>=aux){ aux=r; if(band){ escribir(archf2,r); }else{ escribir(archf3,r); } }else{ aux=r; if(band){ escribir(archf3,r); band=false; }else{ escribir(archf2,r); band=true; } } } cerrar(archf); cerrar(archf2); cerrar(archf3); } void particionFusion(int archfa, int archfb, int archfc, int registro aux, r1, boolean band, dele1,
archfd){ r2; dele2;
abrirL(archfa); abrirL(archfb); abrirE(archfc); abrirE(archfd); band
= leer(archfa, leer(archfb, aux
dele1 while((!fin(archfa) dele2!=true)){
||
aux = dele2 dele1!=true)
&&
true; &r1); &r2); if(r1<=r2) = r1; else = r2; = false; (!fin(archfb) ||
if(dele1){ leer(archfa, &r1); dele1=false; } if(dele2){
leer(archfb,
&r2); dele2=false; } if(r1=aux){ //printf("probando... aux %d, r1 %d, r2 %d\n", aux, r1, r2); ayuda1(&aux,
r1,
archfc,
archfd, band); dele1=true; } else if(r2>=aux){ //printf("probando... r1 %d, aux %d, r2 %d\n", r1, aux, r2); ayuda1(&aux, r2, archfc, archfd, band); dele2=true; } else{ //printf("probando... r1 %d, r2 %d, aux %d\n", r1, r2, aux); ayuda2(&aux,
r1,
archfc, archfd, dele1 =
&band); true; } } else{ if(r2>=aux){ //printf("probando... aux %d, r2 %d, r1 %d\n", aux, r2, r1); ayuda1(&aux, r2, archfc, archfd, band); dele2=true; } else if(r1>=aux){ //printf("probando... r2 %d, aux %d, r1 %d\n", r2, aux, r1); ayuda1(&aux, r1, archfc, archfd, band); dele1=true; } else{ //printf("probando... r2 %d, r1 %d, aux %d\n", r2, r1, aux); ayuda2(&aux, r2, archfc, archfd, &band); dele2 = true; } } } //fin del while if(dele1 && fin(archfa)) ayuda3(&aux, r2, archfb, archfc, archfd, &band); if(dele2 && fin(archfb)) ayuda3(&aux, r1, archfa, archfc, archfd, &band); cerrar(archfa); cerrar(archfb); cerrar(archfc);
cerrar(archfd); }