El método de ordenación por mezcla directa es probablemente el más utilizado por su fácil comprensión.
La idea central de este algoritmo consiste en la realización sucesiva de una partición y una fusión que produce secuencias ordenadas de longitud cada vez mayor. En la primera pasada la partición es de longitud 1, y la fusión o mezcla produce secuencias ordenadas de longitud 2. En la segunda pasada la partición es de longitud 2, y la fusión o mezcla produce secuencias ordenadas de longitud 4. Este proceso se repite hasta que la longitud de la secuencia de la secuencia para la partición sea mayor o igual que el número de elementos del archivo original.
Ejemplo:
Supóngase que se desea ordenar las claves del archivo F. para realizar tal actividad se utilizan dos archivos auxiliares a los que se les denominará. F1 y F2.
F: 09 75 14 68 29 17 31 25 04 05 13 18 72 46 61.
Primera pasada:
Partición en secuencias de longitud 1.
F1: 09’ 14’ 29’ 31’ 04’ 13’ 72’ 61’
F2: 75’ 68’ 17’ 25’ 05’ 18’ 46’
Fusión en secuencias de longitud dos:
F: 09 75’ 14 68’ 17 29’ 25 31’ 04 05’ 13 18’ 46 72’ 61’
Segunda pasada:
Partición de secuencia de longitud 2
F1: 09 75’ 17 29’ 04 05’ 46 72’
F2: 14 68’ 25 31’ 13 18’ 61’
Fusión en secuencias de longitud 4.
F: 09 14 68 75’ 17 25 29 31’ 04 05 13 18’ 46 61 72’
Tercera pasada.
Partición en secuencia de longitud 4.
F1: 09 14 68 75’ 04 05 13 18’
F2: 17 25 29 31’ 46 61 72’
Fusión en secuencias de longitud 8
F: 09 14 17 25 29 31 68 75’ 04 05 13 18 46 61 72’
Cuarta pasada.
Partición en secuencia de longitud 8
F1: 09 14 17 25 29 31 68 75’
F2: 04 05 13 18 46 61 72’
Fusión en secuencias de longitud 16
F: 04 05 09 13 14 17 18 25 29 31 46 61 68 72 75
Imagen:
Código:
APP Mezcla Directa.cpp:
#include<iostream>
using namespace std;
#include"gotoxy.h"
#include"Clase_Mezcla_Directa.h"
#include"Menu_Mezcla_Directa.h"
int main(){
Menu_Mezcla_Directa();
return 0;
}
Clase_Mezcla_Directa.h:
#include<fstream> //Libreria para los ficheros
class MezclaDirecta{
private:
int N;
//-- Metodos de los ficheros --//
void abrir(fstream *f, char nom[], int tip=1);
void cerrar(fstream *f);
//-- Metodos de auxiliares de la ordenación --//
void particiona(int longitud);
void fusiona(int longitud);
public:
MezclaDirecta(){N=0;}
//-- Metodos de los ficheros --//
void limpiar();
bool hayDatos(char nom[]);
void mostrar(char nom[]);
void insertar(int d, char nom[]);
//-- Metodo de ordenacion --//
void ordenar();
};
//-- Metodos para los ficheros --//
void MezclaDirecta::abrir(fstream *f, char nom[], int tip){
if(tip==1) //LECTURA
(*f).open(nom, ios::in );//->
//MODO TEXTO (Acceder a los datos) usaré ">>"
else if(tip==2) //ESCRITURA SIN BORRAR
(*f).open(nom, ios::out | ios::app); //->
//MODO TEXTO (Colocar datos y no borrará) usaré "<<"
else //ESCRITURA y BORRAR
(*f).open(nom, ios::out); //->
//MODO TEXTO (Colocar datos) usaré "<<"
}
void MezclaDirecta::cerrar(fstream *f){
(*f).close();
}
void MezclaDirecta::limpiar(){
fstream F, F1, F2;
abrir(&F, "datos.txt", 3);
abrir(&F1, "F1.txt" , 3);
abrir(&F2, "F2.txt" , 3);
cerrar(&F);
cerrar(&F1);
cerrar(&F2);
}
bool MezclaDirecta::hayDatos(char nom[]){
fstream F;
abrir(&F, nom,1);
int x=-10001;
F>>x;
if(x!=-10001)
return true;
else
return false;
cerrar(&F);
}
void MezclaDirecta::mostrar(char nom[]){
fstream F;
abrir(&F, nom,1);
int dato;
F>>dato;
while(!F.eof()){
cout<<dato<<" ";
F>>dato;
}
cerrar(&F);
}
void MezclaDirecta::insertar(int d, char nom[]){
fstream F;
abrir(&F, nom, 2);
N++;
F<<d<<" ";
cerrar(&F);
}
//-- Metodo propio de Intercalación de Archivo --//
void MezclaDirecta::ordenar(){
int longitud=1;
while( longitud < N){
particiona(longitud);
fusiona(longitud);
longitud*=2;
}
}
void MezclaDirecta::particiona(int longitud){
fstream F, F1, F2;
int con1, con2 , dato;
abrir(&F, "datos.txt",1);
abrir(&F1, "F1.txt" ,3);
abrir(&F2, "F2.txt" ,3);
while(!F.eof()){
con1=0;
while(con1< longitud && !F.eof()){
F>>dato;
if(!F.eof())
F1<<dato<<" ";
con1++;
}
con2=0;
while(con2< longitud && !F.eof()){
F>>dato;
if(!F.eof())
F2<<dato<<" ";
con2++;
}
}
cerrar(&F);
cerrar(&F1);
cerrar(&F2);
}
void MezclaDirecta::fusiona(int longitud){
fstream F, F1, F2;
int con1, con2 , dato1, dato2;
bool ban1, ban2;
abrir(&F , "datos.txt",3);
abrir(&F1, "F1.txt" ,1);
abrir(&F2, "F2.txt" ,1);
ban1=ban2=true;
if(!F1.eof()){
F1>>dato1;
ban1=false;
}
if(!F2.eof()){
F2>>dato2;
ban2=false;
}
while( (!F1.eof() || ban1== false)
&& (!F2.eof() || ban2== false))
{
con1=con2=0;
while( (con1< longitud && ban1 ==false)
&& (con2< longitud && ban2 ==false))
{
if( dato1 <= dato2){
ban1=true;
con1++;
if(!F1.eof()){
F<<dato1<<" ";//Cambio
F1>>dato1;
ban1=false;
}
}else{
ban2=true;
con2++;
if(!F2.eof()){
F<<dato2<<" ";//Cambio
F2>>dato2;
ban2=false;
}
}
}// Fin del segundo while
if( con1 < longitud){
while( con1 < longitud && ban1==false){
ban1=true;
con1++;
if(!F1.eof()){
F<<dato1<<" ";//Cambio
F1>>dato1;
ban1=false;
}
}
}
if( con2 < longitud){
while( con2 < longitud && ban2==false){
ban2=true;
con2++;
if(!F2.eof()){
F<<dato2<<" ";//Cambio
F2>>dato2;
ban2=false;
}
}
}
}//fin del primer while
//Cambios
while(!F1.eof()){
F1>>dato1;
if(!F1.eof())
F<<dato1<<" ";
}
while(!F2.eof()){
F2>>dato2;
if(!F2.eof())
F<<dato2<<" ";
}
cerrar(&F);
cerrar(&F1);
cerrar(&F2);
}
Menu_Mezcla_Directa.h:
void Menu_Mezcla_Directa(){
MezclaDirecta A;
char *z[1];
char *principal[5]={"MENU METODO DE MEZCLA DIRECTA:",
"INGRESAR DATOS.",
"ORDENAR LOS DATOS.",
"MOSTRAR LOS DATOS.",
"ATRAS"};
char *a[5]={"MENU METODO DE MEZCLA DIRECTA (INGRESAR):",
"INGRESAR UN NUMERO.",
"INGRESAR VARIOS NUMEROS.",
"INGRESAR 5 NUMEROS ALEATORIOS.",
"ATRAS."};
int op1=1, op2, op3, N, dato;
A.limpiar(); srand(0);
do{
op1=construirMenu(principal, 5, op1 + 1);
switch(op1){
case 1:
op2=1;
do{
op2=construirMenu(a, 5, op2 + 1);
if(op2==1 || op2==2){ //UNO O VARIOS DATOS.
N=1;
while(op2==2 && (N<=1 || N>=1000)){
z[0]="Digite cuantos datos desea ingresar:";
construirMenu(z,1);
cin>>N;
}
for(int i=0; i<N ; i++){
do{
z[0]="Digite un dato para colocarlo:";
construirMenu(z,1);
cin>>dato;
}while(dato<-10000 || dato>10000);
A.insertar(dato, "datos.txt");
z[0]="Se ha colocado el dato.";
construirMenu(z,1);
system("pause>>NULL");
}
}else if(op2==3){ //DATOS ALEATORIOS.
int RND;
z[0]="Se han colocado los datos aleatorios.";
construirMenu(z,1);
for(int i=0; i<5 ; i++){
do{
RND=rand() % 1000 - 250;
}while(RND<-1000 || RND>1000);
cout<<RND<<" ";
A.insertar(RND,"datos.txt");
}
system("pause>>NULL");
}
}while(op2!=4);
break;
case 2:
if(A.hayDatos("datos.txt")){//Si hay datos.
z[0]="Se ha ordenado el ficheros.";
A.ordenar();
}else
z[0]="No hay datos en el fichero.";
construirMenu(z,1);
system("pause>>NULL");
break;
case 3:
if(A.hayDatos("datos.txt")){//Si hay datos.
z[0]="Los datos son: ";
construirMenu(z,1);
A.mostrar("datos.txt");
}else{
z[0]="No hay datos en el fichero.";
construirMenu(z,1);
}
system("pause>>NULL");
break;
}
}while(op1!=4);
}
gotoxy.h:
#include<iostream>
#include<cstdlib>
#include<conio.h>
#include<windows.h>
using namespace std;
void limpiar(){
system("cls");
fflush(stdin);
cin.clear();
}
void texcolor(int x){
SetConsoleTextAttribute(GetStdHandle (STD_OUTPUT_HANDLE),x);
}
void gotoxy(int x, int y) {
COORD Cursor_Pos = {x,y};
SetConsoleCursorPosition(GetStdHandle (STD_OUTPUT_HANDLE), Cursor_Pos);
}
int construirMenu(char *opciones[], int can, int seleccion=2, int X=15, int Y=3){
bool ban=true;
int i,lim, tecla, opc=seleccion;
limpiar();
do{
//-- Buscar la frase más larga --//
for(lim=i=0; i<can && ban; i++){
if(strlen(opciones[i])>lim)
lim=strlen(opciones[i]);
}
for(i=Y; i<=(can + Y + 1) && ban; i++){
gotoxy(X, i);
//-- Esquinas y lineas verticales del lado izquierdo. --//
if(i==Y) cout<<"É";
else if(i!=can + Y + 1) cout<<"º";
else cout<<"È";
//-- Lineas horizontales y las opciones.--//
if(i==Y || i==can + Y + 1){
for(int j=0; j<lim + 6; j++) cout<<"Í";
}else{
//-- Cambio de Color --//
if(opc==i- Y)
texcolor(4);
//-- Las letras --//
if(i- (Y + 1) == 0)
gotoxy(X + 1 +(lim + 1 - strlen(opciones[i- (Y + 1)]))/2,i); // Centrado
else
gotoxy(X + 1, i);
cout<<" "<<opciones[i- (Y + 1)];
texcolor(7);
}
//-- Esquinas y lineas verticales del lado derecho. --//
gotoxy(X + lim + 6 + 1, i);
if(i==Y) cout<<"»";
else if(i!=can + Y + 1) cout<<"º";
else cout<<"¼";
}
//-- Funciones de reconocer las teclas --//
if(can==1){
gotoxy(X, i);
return 0;
}else
tecla = getch();
if(tecla==72){
if(opc!=2)//-- Flecha Arriba del teclado
opc--;
else
opc=can;
ban=true;
}else if(tecla==80){//-- Flecha Abajo del teclado
if(opc!=can)
opc++;
else
opc=2;
ban=true;
}else
ban=false;
}while(tecla!=13);
return opc - 1;
}
Descarga el código fuente desde aquí.






excelente}
ResponderEliminar