1 Utilice la recursividad para implementar tres tipos de recorrido de árbol binario: primer orden, orden intermedio y orden final. 2Problema del árbol de Huffman
//Hay recorrido recursivo y recorrido iterativo. Puede escribir archivos y comprimir código. Puedes leer archivos.
//Si no necesita ninguna función, simplemente elimine la función correspondiente.
//Espero conseguir puntos extra.
# incluir ltiostream gt
# incluir ltfstream gt
# incluir ltiomanip gt
# incluir ltstring gt
Usar espacio de nombres std
const int maxlen = 10000; //Número máximo de nodos
const int maxlen2 = 260 //Número máximo de caracteres, número máximo de nodos hoja
const int maxchar = 260 //Número máximo de caracteres
# define int max 10000000; //Número grande, mayor que cualquier peso.
Struct CharSet //Guarda la estructura de caracteres y nodos cuando se inicializa el programa.
{
char ch
int peso
};
Estructura nodo Huffman // árbol Huffman estructura de nodo
{
int peso, padre, lchild, rchild
char ch
haff node(){ peso = 0; parent = l child = rchild =-1; ch = '\n}
};
Estructura Codificación Huffman // Estructura de información de codificación de caracteres del árbol Huffman
{
Unsigned int bit; // Una cadena de códigos binarios se representa mediante un número entero sin signo mediante operaciones de bits.
int startb//Desplazamiento del registro.
int peso;
char ch
código haff(){ bit = 0; startb =-1;
Haff code amoperator = (haff code amp; Obj) //Símbolo de asignación sobrecargado
{
bit = obj.bitstartb = obj.startb
ch = obj . nivel del sistema
{
Privado:
CharSet cs[maxlen/2] //Guarda la información de caracteres y peso durante la inicialización.
haff node HN[maxlen]; //Guardar la información del nodo del árbol Huffman.
haff code HC[maxlen/2]; //Guarda la información de codificación de caracteres del árbol Huffman.
código haff hc2[max char]; //Hash del índice. Teniendo en cuenta que la cantidad de caracteres es pequeña, los dígitos decimales de los caracteres se utilizan como subíndices para guardar e indexar la información de codificación de caracteres, y el tiempo es O (1);
int head//Array subscript del nodo raíz.
int n;
int leafnum//Número de nodos de hoja y número de caracteres.
Público:
HaffmanSystem(){ n = cabeza = hoja num = 0;}
void Huffman(); // Árbol de Huffman Generar función.
void inicialization(); //Inicializa y llama a Huffman();
void encoding(); //Codifica el archivo "ToBeTran".
void decode(); //Decodifica el archivo "CodeFile".
void print(); //Imprime el código en la pantalla.
Static void TreePrinting(int pos, int i, int child_flag, HaffmanSystem * p, ofstream ampfop);
void tree print() // Genera el gráfico del árbol Huffman en Screens; y archivos donde las funciones recursivas se completan llamando a funciones de instancia estáticas.
void TreeFromFile(); //Obtiene el árbol de Huffman del archivo.
};
void haffman system::initialization()
{
cout lt lt tamaño del conjunto de caracteres n (espacio no incluido )
CIN gt; gtn;
for(int I = 0; i ltn; i)
{
cout lt lt "Primero"
CIN gt; gtcs[i]. ch gt gtcs[yo]. Peso;
}
cout lt ltFinalmente, ingrese el peso del espacio (menor o igual a 0 significa que el espacio no existe)
CIN gt ; gtcs[n] . Peso;
cs[n]. ch = "";
if(cs[n].weight gt0)n;
This-gt; // Llama a la función de generación del árbol de Huffman.
}
//Función de generación de árbol de Huffman.
sistema void Huffman::Huffman()
{
hoja num = n
int i, j , m1, m2; , k1, k2;
for(I = 0; iltn;i)
{
hn[i]. peso = cs[i]. Peso;
hn[i]. ch = hc[yo]. ch = cs[yo]. ch;
}
for(I = 0;iltn-1;I) //n-1 nodos de rama;
{
m 1 = m2 = int max; k 1 = k2 = 0;
for(j = 0; j ltn I; j )
{
if(m 1 gt; hn[j]. peso y peso. amphn[j]. parent==-1)
{
m2 = m 1; 1;
m1 = hn[j]. peso; k 1 = j;
}
Otro
if (m2 gthn[j].peso y peso.amphn[j].parent== -1)
{
m2 = hn[j]. peso;k2 = j;
}
}
hn[k1]. padre = n I;hn[k2].
padre = n I;
hn[n i]. peso = hn[k1]. Peso hn[k2]. Peso;
hn[n i]. l niño = k 1; hn[n i]. rchild = k2
head = n I;
}
int child, parent
for(I = 0; i ltn; i )
{
hc[i]. peso = hn[i]. peso;
niño = I;
padre = hn[niño]. Padre;
Y (padre!= -1)
{
if(HN[padre].lchild == niño)
{
hc[i]. startb
}
else if(hn[padre].rchild == niño)
{
hc[i]. bit = hc[i]. bit | (1 lt; lt hc[i].startb);
}
niño = padre
padre = hn[niño]. Padre;
}
hc2[hc[i]. ch]= HC[I];
}
char Choice = ' N
cout lt lt"Si desea guardar el árbol Huffman actual en hfmTree .dat? " lt ltendl
CIN gt; gt selección;
If(choice=='y'||choice=='Y') //se generará The Havermann El árbol se guarda en el archivo hfmTree.dat
{
ofstream fop
fop.open("hfmTree.dat ", IOs:: out | IOs: :binary | IOs: :trunc);
if (!fop){ cout lt; lt "Error al abrir el archivo, falló al guardar" < ltendl return }
fop .write( (char *)&leafnum,sizeof(hoja num));
for(I = 0;ilt2 * hoja num-1;i)
{
fop .write((char *)&hn[i],sizeof(HN[I]);
}
for(I = 0;iltmaxchari)
{
fop . escribir((char *) amp; hc2[i], sizeof(hc2[I]);
}
fop . cerrar ();
cout lt lt"¡Guardado correctamente!" lt ltendl
}
}
/ /función de codificación.
void HaffmanSystem::Encoding()
{
if(leaf num == 0){ árbol del archivo();}
char ch
int i, num=0, bitTemp, startTemp=-1, temp 2 = 0;
ifstream fip2("ToBeTran.txt", IOs::in );
if (! FIP 2) { cout lt; lt "¡El archivo ToBeTran.txt especificado no se puede abrir!" lt ltendl regresa }
while(FIP 2. get; ( ch)){ num;}
FIP 2. close();
de flujo fop 1("codefile. dat", IOs::out|IOs::trunc| IOs ::binary);
if (!fop 1){ cout lt; lt "¡El archivo especificado CodeFile.dat no se puede abrir!" lt ltendl devuelve }
ofstream fop2; (" CodePrin.txt ", IOs::out | IOs::trunc);
if (!fop 2){ cout lt; "No se puede abrir el archivo especificado CodePrin.txt! " lt ltendl return ; }
ifstream FIP 1("tobe tran . txt", IOs::in);
if (! FIP 1) { cout lt "El archivo especificado por ToBeTran no se puede abrir. txt! " lt ltendl regresa; }
fop 1. write((char *) amp; num, sizeof(num)); //El número de caracteres escritos primero.
char bit buf = 0; //Utilice un espacio de carácter para almacenar datos binarios en el buffer y escriba cada ocho bits en el archivo codificado.
cout lt lt" \nEl archivo que se codificará como tran . txt: ";
for(I = 7;;I-)
{
if(i==-1)
{
//Utilice un bitBuf de espacio de caracteres para almacenar datos binarios en el buffer y escribir cada ocho bits en el archivo codificado.
fop 1. write((char *) & bitBuf, sizeof(bitBuf));
I = 7; bit buf = 0 // Carácter inicial, convirtiéndolo en binario "; 00000000";
}
if(start temp lt;0)
{
if(num- lt;= 0) Desconectar;
FIP 1. get(ch);
cout lt ltch;
bitTemp = hc2[ch-0]. poco;
startTemp = hc2[ch-0]. startb
}
//Operación de bit para determinar si un bit es 0 o 1.
temp 2 =(1 amp; bitTemp gt gtstart temp-);
if(temp 2)fop 2 lt "1"; fop2 lt lt"0";
bitBuf = bitBuf | temp2 lt ltI;
//O operación bit a bit, en la que 0 o 1 se combina con el carácter original para obtener una nueva codificación. información . Por ejemplo, 00010000 | 1
}
fop 1. write((char *) amp; bitBuf, sizeof(bitBuf)); //Escribe el último segmento en el archivo.
FIP 1 . close();
fop 1 .
fop 2. close();
cout lt lt" \ n \ n \¡Codificación exitosa!" >//Función de decodificación.
void HaffmanSystem::Decoding()
{
if(leaf num == 0){ árbol del archivo();}
ofstream fop("TextFile.txt", IOs::out | IOs::trunc);
if (!fop){ cout lt"El archivo especificado [textfile.txt] no puede ser abrió "
ifstream fip("CodeFile.dat", IOs::in);
if (!FIP){ cout lt; lt"El archivo especificado [codefile.dat no puede abrir] ]"
char ch, bitBuf
int num, bitTemp=-1, start temp =-1;
int FLAG=0, padre = head
FIP . read((char *) amp; num, sizeof(num));
cout lt lt" resultado de decodificación:
for(int I =-1; num gt0; i-)
{
if(i==-1)
{
FIP . read((char *) amp; bitBuf, sizeof(bitBuf));
I = 7; Al igual que la codificación, existe el mismo manejo elegante de mapas de bits que ahorra tiempo y espacio.
FLAG = (1 lt; ltI) y ampbitBuf
If(FLAG==0) //0 queda
{
padre = hn[padre]. lniño
}
Else //1derecho
{
padre = hn[padre]. rchild
}
//Buscar de arriba a abajo. Cuando tocas un nodo hoja, encontrarás caracteres de nodo.
if(HN[padre].lchild = =-1 amp; ampHN[padre].rchild==-1)
{
ch = HN [Padre].
ch;
cout lt ltch;
fop lt ltch;
parent=head;
num-;
}
}
cout lt ltendl
FIP . >
cout lt lt"¡Decodificación exitosa!" lt ltendl
}
//Función de codificación de impresión.
void HaffmanSystem::Print()
{
ifstream fip("CodePrin.txt", IOs::in);
if (! FIP) { cout lt; lt "No se puede abrir el archivo especificado [codeprin.txt]"
int j = 0
char ch
cout lt lt"Archivo de codificación de caracteres codeprin.txt:";
while(FIP gt; gtch)
{
if(j 50 = = 0 )cout lt; ltendl//50 caracteres para nueva línea.
j;
cout lt ltch;
}
cout lt ltendl
FIP close(). ;
}
//Muestre el árbol de Huffman en la pantalla y guárdelo en el archivo TreePrint.txt
void haffman system::tree Printing()
{
if(leaf num = = 0){ árbol del archivo();}
ofstream fop("TreePtint.txt", IOs:: out | IOs::trunc);
if (!fop){ cout lt; lt "No se puede abrir el archivo especificado TreePtint.txt!" lt" Muestra visualmente el árbol binario (pesos entre paréntesis) 90 grados en sentido antihorario:\n "
fop lt lt" Muestra visualmente el árbol binario (pesos entre paréntesis) 90 grados en sentido antihorario:\n "
TreePrinting(head, 1, 2, this, fop); //fop pasa una secuencia de archivo que se utiliza para generar el mismo archivo en todos los niveles de recursividad.
cout lt ltendl
fop . close();
}
// Función de salida, implementación estática, conveniente para llamadas recursivas. .
void haffman system::tree print(int pos, int i, int child_flag, HaffmanSystem * p, ofstream ampfop)
{// Imita el libro de texto para generar un árbol binario.
if(pos gt;= 0 amp amppos lt= p->;head)
{
impresión de árbol(p- gt;HN[posición] .
rchild, i 1, 1, p, fop);
for(int j = 0; j lt4 *(I-1); j ){ cout lt" "; ;}
if(child _ flag = =-1){ cout lt"\\";fop lt lt"\\";}
else if(child _ bandera = = 1) { cout lt "/"; fop lt "/" }
if (p->HN[posición].ch == '\n'){ cout lt; ; lt"-NULL " lt; ltendlfop lt"-NULL " lt; ltendl}
Otro
{
cout lt"-" lt; ltp->HN[posición]. ch lt lt"(" lt ltp->HN[posición]. peso lt lt")" lt ltendl
fop lt lt"-" lt;ltp->HN[posición]. ch lt lt"(" lt ltp->; HN[posición]. peso lt lt")" lt ltendl
}
impresión de árbol(p- gt; HN[posición] .lchild,i 1,-1,p,fop);
}
}
sistema void haffman::TreeFromFile()
{
int I;
cout lt lt"El árbol de Huffman no está en la memoria, intentando leer el árbol de Huffman desde el archivo..."< ltendl p >
archivo ifstream;
file.open("hfmTree.dat ", IOs::in | IOs::binary);
if (!file){ cout lt lt "¡El archivo hfmTree.dat especificado no se puede abrir!" lt ltendl devuelve }
if(file . eof()){ cout lt"El archivo del árbol Huffman está vacío, inicialícelo; ! " lt ltendl devuelve; }
archivo . read((char *) & leafnum, sizeof(leaf num));
head = leaf num * 2-2;
for(I = 0;i lt2 * hoja num-1;i)
{
archivo read((char *) amp;hn[i. ], tamaño de(HN[I]);
}
for(I = 0; ilt= maxchari)
{
archivo . read((char *) & hc2[i], tamañode(hc2[I]);
}
archivo . close();
}
//Función principal.
int main()
{
sistema haffman * T = nuevo sistema haffman()
char elección = ' Y<; /p>
Y (select!='0')
{
cout lt lt "-" lt; ltendl
cout lt ltSTD: :left lt; ltsetw(12) lt; lt" 1-Inicialización"
cout lt lt"-" lt; ltendl
cout lt ltSTD: :right ltsetw(40) ) lt; lt" operación: ";
CIN gt;
Cambiar (seleccionar)
{
Caso" 0": { cout lt; lt "El sistema ha salido"
Caso '1': { T-gt; inicialización(); roto; }
Caso "2": { T- gt; codificar(); romper }
Caso "3": { T- decodificar(); - gt;print();break;}
Caso "5": { T- gt;tree print();break;}
Predeterminado: break
}
}
Devuelve 0;
}