//There are recursive traversal and iterative traversal. You can write files and compress code. You can read the file.
//If no function is needed, just delete the corresponding function.
//I hope I can get extra points.
# include & ltiostream & gt
# include & ltfstream & gt
# include & ltiomanip & gt
# include & lt string & gt
Use namespace std
const int maxlen = 10000; //Maximum number of nodes
Const int maxlen2 = 260// Maximum number of characters, maximum number of leaf nodes.
Const int maxchar = 260// Maximum number of characters.
# define int max 10000000; //A large number, greater than any weight.
Struct CharSet // The structure of characters and nodes is saved when the program is initialized.
{
char ch
Int weight;
};
Structure Huffman node//Huffman tree node structure
{
int weight,parent,lchild,rchild
char ch
haff node(){ weight = 0; parent = l child = rchild =- 1; ch = ' \ n}
};
Structure Huffman coding//Huffman tree character coding information structure
{
Unsigned int bit; //A string of binary codes is represented by an unsigned integer through bit operation.
Int startb// records the offset.
Int weight;
char ch
haff code(){ bit = 0; startb =- 1; Weight = 0; ch = ' \ n}
Huff code & operator = (haffcode &; Obj) // Overload assignment symbol
{
bit = obj.bitstartb = obj.startb
ch = obj . ch; weight = obj.weight
Return * this
}
};
Huffman system level
{
Private:
CharSet cs[maxlen/2]; //Save the character and weight information during initialization.
haff node HN[maxlen]; //Save Huffman tree node information.
haff code HC[maxlen/2]; //Save Huffman tree character encoding information.
haff code hc2[max char]; //index hash. Considering the small number of characters, the decimal places of characters are used as subscripts to save and index the character coding information, and the time is o (1);
Int head// array subscript of the root node.
int n;
Int leafnum// Number of leaf nodes and characters.
Public:
HaffmanSystem(){ n = head = leaf num = 0; }
Void Huffman (); //Huffman tree generating function.
void initial ization(); //Initialize and call Huffman ();
Void encoding (); //encode the file "ToBeTran".
Void decoding (); //Decode the file "CodeFile".
Void print (); //Print the code to the screen.
Static void TreePrinting(int pos, int i, int child_flag, HaffmanSystem * p, ofstream & fop);
void tree printing(); //Output Huffman tree graphics to screen and file, in which static instance function is called to complete recursive function.
void TreeFromFile(); //Get the Huffman Tree from the file.
};
void haffman system::initial ization()
{
Cout & lt& lt character set size n (excluding spaces)
CIN & gt; & gtn;
for(int I = 0; I & ltn;; i++)
{
Cout & lt& lt "first"
CIN & gt; & gtcs[i]。 ch & gt& gtcs[i]。 Weight;
}
Cout & lt& lt Finally, enter the weight of the space (less than or equal to 0 means the space does not exist).
CIN & gt; & gtcs[n]。 Weight;
cs[n]。 ch =“”;
If(cs[n]. Weight & gt0) n++;
This-> Huffman (); //Call the Huffman tree generation function.
}
//Huffman tree generating function.
Void Huffman system:: Huffman ()
{
leaf num = n;
int i,j,m 1,m2,k 1,k2;
for(I = 0; I & ltn;; i++)
{
hn[i]。 Weight = cs[i]. Weight;
hn[i]。 ch = hc[i]。 ch = cs[i]。 ch;
}
for(I = 0; I<n-1; I++) //n- 1 branch nodes;
{
m 1 = m2 = int max; k 1 = k2 = 0;
for(j = 0; j & ltn+I; j++)
{
if(m 1 & gt; hn[j]。 Weight and weight. & amphn[j]。 parent==- 1)
{
m2 = m 1; k2 = k 1;
m 1 = hn[j]。 Weight; k 1 = j;
}
other
If (m2 & gthn[j]. Weight and weight. & amphn[j]。 parent==- 1)
{
m2 = hn[j]。 Weight; k2 = j;
}
}
hn[k 1]。 parent = n+I; hn[k2]。 parent = n+I;
hn[n+i]。 Weight = hn[k 1]. Weight +hn[k2]. Weight;
hn[n+i]。 l child = k 1; hn[n+i]。 rchild = k2
head = n+I;
}
int child,parent
for(I = 0; I & ltn;; i++)
{
hc[i]。 Weight = hn[i]. Weight;
child = I;
parent = hn[child]。 Parents;
And (parents! = - 1)
{
If(HN[ parent]. lchild == child)
{
++hc[i]。 startb
}
else if(hn[parent].rchild == child)
{
hc[i]。 bit = hc[i]。 bit |( 1 & lt; & lt++hc[i]。 startb);
}
Children = parents;
parent = hn[child]。 Parents;
}
hc2[hc[i]。 ch]= HC[I];
}
char choice = ' N
Cout & lt& lt "Do you want to save the current Huffman tree to hfmTree.dat?" & lt& ltendl
CIN & gt; & gt selection;
If(choice=='y'||choice=='Y') // Save the generated Havermann tree in the file hfmTree.dat
{
ofstream fop
fop.open("hfmTree.dat ",IOs::out | IOs::binary | IOs::trunc);
If (! fop){ cout & lt; & lt "Error in opening file, failed to save" < & ltendl returns; }
fop . write((char *)& amp; leafnum,sizeof(leaf num));
for(I = 0; I<2 * leafnum-1; i++)
{
fop . write((char *)& amp; hn[i],sizeof(HN[I]);
}
for(I = 0; I & ltmaxchari++)
{
fop . write((char *)& amp; hc2[i],sizeof(hc2[I]);
}
fop . close();
Cout & lt& lt "Saved successfully!" & lt& ltendl
}
}
//coding function.
void HaffmanSystem::Encoding()
{
if(leaf num = = 0){ tree from file(); }
char ch
int i,num=0,bitTemp,startTemp=- 1,temp 2 = 0;
ifstream fip2("ToBeTran.txt ",IOs::in);
If (! FIP 2){ cout & lt; & lt "Unable to open the specified file ToBeTran.txt!" & lt& ltendl returned; }
while(FIP 2 . get(ch)){ num++; }
FIP 2 . close();
of stream fop 1(" codefile . dat ",IOs::out | IOs::trunc | IOs::binary);
If (! fop 1){ cout & lt; & lt "Unable to open the specified file CodeFile.dat!" & lt& ltendl returned; }
ofstream fop2("CodePrin.txt ",IOs::out | IOs::trunc);
If (! fop 2){ cout & lt; & lt "Unable to open the specified file CodePrin.txt!" & lt& ltendl returned; }
ifstream FIP 1(" tobe tran . txt ",IOs::in);
If (! FIP 1){ cout & lt; & lt "Unable to open the specified file ToBeTran.txt!" & lt& ltendl returned; }
fop 1 . write((char *)& amp; num,sizeof(num)); //Number of characters written first.
char bit buf = 0; //Buffer binary data with a character space, and write it into the encoded file every eight bits.
Cout & lt& lt" \n nFile tobetran.txt to be encoded: ";
for(I = 7; ; I-)
{
if(i==- 1)
{
//Buffer binary data with a character space bitBuf, and write it into the encoded file every eight bits.
fop 1 . write((char *)& amp; bitBuf,sizeof(bitBuf));
I = 7; bit buf = 0; //Initial character to make it binary "00000000";
}
if(start temp & lt; 0)
{
if(num-& lt; =0) disconnect;
FIP 1 . get(ch);
cout & lt& ltch;
bitTemp = hc2[ch-0]。 Bit;
startTemp = hc2[ch-0]。 startb
}
//bit operation to determine whether a bit is 0 or 1.
temp 2 =( 1 & amp; bitTemp & gt& gtstart temp-);
if(temp 2)fop 2 & lt; & lt" 1";
else fop2 & lt& lt"0";
Bitbuf = bitbuf | temp2 < < me;
//or bitwise operation, where 0 or 1 is combined with the original character to obtain new coding information. Such as 000 10000 | 1
}
fop 1 . write((char *)& amp; bitBuf,sizeof(bitBuf)); //Write the last paragraph to the file.
FIP 1 . close();
fop 1 . close(); //Close the file stream.
fop 2 . close();
Cout & lt& lt" \ n \ n \ Coding succeeded! " & lt& ltendl
}
//decoding function.
void HaffmanSystem::Decoding()
{
if(leaf num = = 0){ tree from file(); }
ofstream fop("TextFile.txt ",IOs::out | IOs::trunc);
If (! fop){ cout & lt; & lt "Unable to open the specified file [textfile.txt]"
ifstream fip("CodeFile.dat ",IOs::in);
If (! FIP){ cout & lt; & lt "Unable to open the specified file [codefile.dat]"
char ch,bitBuf
int num,bitTemp=- 1,start temp =- 1;
int FLAG=0,parent = head
FIP . read((char *)& amp; num,sizeof(num));
Cout < < "decoding result:";
for(int I =- 1; num & gt0; I-)
{
if(i==- 1)
{
FIP . read((char *)& amp; bitBuf,sizeof(bitBuf));
I = 7;
}
//Like coding, decoding has the same elegant bit operation processing, which can save time and space.
FLAG =( 1 & lt; & ltI) and ampbitBuf
If (flag = = 0)//0Left
{
parent = hn[parent]。 lchild
}
Else/1right
{
parent = hn[parent]。 rchild
}
//Search from top to bottom. When you touch a leaf node, you will find the node character.
If(HN[ parent]. lchild = =- 1 & amp; & ampHN[ parents]. rchild==- 1)
{
Ch = HN[ parent]. ch;
cout & lt& ltch;
fop & lt& ltch;
Father = head;
num-;
}
}
cout & lt& ltendl
FIP . close();
fop . close();
Cout & lt& lt "Decoding succeeded!" & lt& ltendl
}
//Print the encoding function.
void HaffmanSystem::Print()
{
ifstream fip("CodePrin.txt ",IOs::in);
If (! FIP){ cout & lt; & lt "Unable to open the specified file [codeprin.txt]"
int j = 0;
char ch
Cout & lt& lt "character encoding file codeprin.txt:";
while(FIP & gt; & gtch)
{
if(j % 50 = = 0)cout & lt; & ltendl//50-character newline.
j++;
cout & lt& ltch;
}
cout & lt& ltendl
FIP . close();
}
//output the Huffman tree to the screen and save it in the TreePrint.txt file.
void haffman system::tree printing()
{
if(leaf num = = 0){ tree from file(); }
ofstream fop("TreePtint.txt ",IOs::out | IOs::trunc);
If (! fop){ cout & lt; & lt "Unable to open the specified file TreePtint.txt!" & lt& ltendl returned; }
Cout & lt& lt" 90-degree counterclockwise intuitive output binary tree (weight in brackets): \ n "
Fop<& lt" 90-degree counterclockwise intuitive output binary tree (weight in brackets): \ n "
TreePrinting(head, 1,2,this,fop); //fop passes a file stream that is used to output the same file at all levels of recursion.
cout & lt& ltendl
fop . close();
}
//output function, static implementation, convenient recursive call.
void haffman system::tree printing(int pos,int i,int child_flag,HaffmanSystem * p,ofstream & ampfop)
{//Imitate the textbook and output a binary tree.
if(pos & gt; = 0 & amp& amppos & lt= p->; Head)
{
tree printing(p-& gt; HN[ location]. rchild,i+ 1, 1,p,fop);
for(int j = 0; j & lt4 *(I- 1); j++){ cout & lt; & lt" "; fop & lt& lt" "; }
if(child _ flag = =- 1){ cout & lt; & lt"\\"; fop & lt& lt"\\"; }
else if(child _ flag = = 1){ cout & lt; & lt"/"; fop & lt& lt"/"; }
If (p->; HN[ location]. ch = = ' \ n '){ cout & lt; & lt"-NULL " & lt; & ltendlfop & lt& lt"-NULL " & lt; & ltendl}
other
{
cout & lt& lt“-”& lt; & ltp->; HN[ location]. ch & lt& lt"(" & lt& ltp->; HN[ location]. Weight < < ")" < < endl
fop & lt& lt“-”& lt; & ltp->; HN[ location]. ch & lt& lt"(" & lt& ltp->; HN[ location]. Weight < < ")" < < endl
}
tree printing(p-& gt; HN[ location]. lchild,i+ 1,- 1,p,fop);
}
}
void haffman system::TreeFromFile()
{
int I;
Cout & lt& lt "Huffman tree is not in memory, try to read Huffman tree from file ..." < & ltendl.
Ifstream file;
file.open("hfmTree.dat ",IOs::in | IOs::binary);
If (! file){ cout & lt; & lt "Unable to open the specified file hfmTree.dat!" & lt& ltendl returned; }
if(file . eof()){ cout & lt; & lt "Huffman tree file is empty, please initialize!" & lt& ltendl returned; }
file . read((char *)& amp; leafnum,sizeof(leaf num));
head = leaf num * 2-2;
for(I = 0; I<2 * leafnum-1; i++)
{
file . read((char *)& amp; hn[i],sizeof(HN[I]);
}
for(I = 0; I<= maxchari++)
{
file . read((char *)& amp; hc2[i],sizeof(hc2[I]);
}
file . close();
}
//main function.
int main()
{
haffman system * T = new haffman system();
char choice = ' Y
And (choose! ='0')
{
cout & lt& lt“-”& lt; & ltendl
cout & lt& ltSTD::left & lt; & ltsetw( 12)& lt; & lt" 1- initialization "
cout & lt& lt“-”& lt; & ltendl
cout & lt& ltSTD::right & lt; & ltsetw(40)& lt; & lt' operation:';
CIN & gt; & gt selection;
Switch (selection)
{
Case "0": {cout <; & lt "System has exited"
Case'1':{t-> initial ization(); Break; }
Case "2": {t->; Code (); Break; }
Case "3": {t->; Decoding (); Break; }
Case "4": {t->; print(); Break; }
Case "5": {t->; tree printing(); Break; }
Default: break
}
}
Returns 0;
}