数据结构哈夫曼树编码译码实验报告.docx
- 文档编号:30385067
- 上传时间:2023-08-14
- 格式:DOCX
- 页数:26
- 大小:225.49KB
数据结构哈夫曼树编码译码实验报告.docx
《数据结构哈夫曼树编码译码实验报告.docx》由会员分享,可在线阅读,更多相关《数据结构哈夫曼树编码译码实验报告.docx(26页珍藏版)》请在冰豆网上搜索。
数据结构哈夫曼树编码译码实验报告
【详细设计】
具体代码实现如下:
//HaffmanTree.h
#include
#include
#include
structHuffmanNode//哈夫曼树的一个结点
{
intweight;
intparent;
intlchild,rchild;
};
classHuffmanTree//哈夫曼树
{
private:
HuffmanNode*Node;//Node[]存放哈夫曼树
char*Info;//Info[]存放源文用到的字符——源码,如'a','b','c','d','e',此内容可以放入结点中,不单独设数组存放
intLeafNum;//哈夫曼树的叶子个数,也是源码个数
public:
HuffmanTree();
~HuffmanTree();
voidCreateHuffmanTree();/*在内存中建立哈夫曼树,存放在Node[]中。
让用户从两种建立哈夫曼树的方法中选择:
1.从键盘读入源码字符集个数,每个字符,和每个字符的权重,建立哈夫曼树,
并将哈夫曼树写入文件hfmTree中。
2.从文件hfmTree中读入哈夫曼树信息,建立哈夫曼树*/
voidCreateHuffmanTreeFromKeyboard();
voidCreateHuffmanTreeFromFile();
voidEncoder();/*使用建立好的哈夫曼树(如果不在内存,则从文件hfmTree中读入并建立内存里的哈夫曼树),
对文件ToBeTran中的正文进行编码,并将码文写入文件CodeFile中。
ToBeTran的内容可以用记事本等程序编辑产生。
*/
voidDecoder();/*待译码的码文存放在文件CodeFile中,使用建立好的哈夫曼树(如果不在内存,
则从文件hfmTree中读入并建立内存里的哈夫曼树)将码文译码,
得到的源文写入文件TextFile中,并同时输出到屏幕上。
*/
voidPrintCodeFile();/*将码文文件CodeFile显示在屏幕上*/
voidPrintHuffmanTree();/*将哈夫曼树以直观的形式(凹入表示法,或广义表,或其他树形表示法)显示在屏幕上,
同时写入文件TreePrintFile中*/
voidPrintHuffmanTree_aoru(intT,intlayer=1);/*凹入表示法显示哈夫曼树,由PrintHuffmanTree()调用*/
};
///////////////////////////////////////////////////////////////////HuffmanTree.cpp
#include
#include
#include"HuffmanTree.h"
usingnamespacestd;
//******************************************************
HuffmanTree:
:
HuffmanTree()
{
Node=NULL;
}
//******************************************************
HuffmanTree:
:
~HuffmanTree()
{
delete[]Node;
}
//******************************************************
voidHuffmanTree:
:
CreateHuffmanTree()
{
charChoose;
cout<<"你要从文件中读入哈夫曼树(按1),还是从键盘输入哈夫曼树(按2)?
";
cin>>Choose;
if(Choose=='2'){//键盘输入建立哈夫曼树
CreateHuffmanTreeFromKeyboard();
}//choose=='2'
else{//从哈夫曼树文件hfmTree.dat中读入信息并建立哈夫曼树
CreateHuffmanTreeFromFile();
}
}
//******************************************************
voidHuffmanTree:
:
CreateHuffmanTreeFromKeyboard()
{
intNum;
cout<<"\n请输入源码字符集个数:
";
cin>>Num;
if(Num<=1)
{
cout<<"无法建立少于2个叶子结点的哈夫曼树。
\n\n";
return;
}
LeafNum=Num;
Node=newHuffmanNode[2*Num-1];
Info=newchar[2*Num-1];
for(inti=0;i cout<<"请输入第"< getchar(); Info[i]=getchar();//源文的字符存入字符数组Info[] getchar(); cout<<"请输入该字符的权值或频度"; cin>>Node[i].weight;//源文的字符权重存入Node[].weight Node[i].parent=-1; Node[i].lchild=-1; Node[i].rchild=-1; } for(i=Num;i<2*Num-1;i++) {//循环建立哈夫曼树内部结点 intpos1=-1,pos2=-1; intmax1=32767,max2=32767; for(intj=0;j if(Node[j].parent==-1)//是否为根结点 if(Node[j].weight { max2=max1; max1=Node[j].weight; pos2=pos1; pos1=j; } else if(Node[j].weight { max2=Node[j].weight; pos2=j; } Node[pos1].parent=i; Node[pos2].parent=i; Node[i].lchild=pos1; Node[i].rchild=pos2; Node[i].parent=-1; Node[i].weight=Node[pos1].weight+Node[pos2].weight; }//for cout<<"哈夫曼树已成功构造完成。 \n"; //把建立好的哈夫曼树写入文件hfmTree.dat charch; cout<<"是否要替换原来的哈夫曼树文件(Y/N): "; cin>>ch; if(ch! ='y'&&ch! ='Y')return; else { ofstreamfop; fop.open("hfmTree.dat",ios: : out|ios: : binary|ios: : trunc);//打开文件 if(fop.fail()) { cout<<"\n哈夫曼树文件打开失败,无法将哈夫曼树写入hfmTree.dat文件。 \n"; return; } fop.write((char*)&Num,sizeof(Num));//先写入哈夫曼树的叶子结点个数 for(i=0;i {//再写入源文字符集的所有字符(存储在Info[]中) fop.write((char*)&Info[i],sizeof(Info[i])); flush(cout); } for(i=0;i<2*Num-1;i++) {//最后写入哈夫曼树的各个结点(存储在Node[]中) fop.write((char*)&Node[i],sizeof(Node[i])); flush(cout); } fop.close();//关闭文件 cout<<"\n哈夫曼树已成功写入hfmTree.dat文件。 \n"; } } //****************************************************** voidHuffmanTree: : CreateHuffmanTreeFromFile() { ifstreamfip; fip.open("hfmTree.dat",ios: : binary|ios: : in); if(fip.fail()) { cout<<"哈夫曼树文件hfmTree.dat打开失败,无法建立哈夫曼树。 \n"; return; } fip.read((char*)&LeafNum,sizeof(LeafNum)); if(LeafNum<=1) { cout<<"哈夫曼树文件中的数据有误,叶子结点个数少于2个,无法建立哈夫曼树。 \n"; fip.close(); return; } Info=newchar[LeafNum]; Node=newHuffmanNode[2*LeafNum-1]; for(inti=0;i fip.read((char*)&Info[i],sizeof(Info[i])); for(i=0;i<2*LeafNum-1;i++) fip.read((char*)&Node[i],sizeof(Node[i])); fip.close(); cout<<"哈夫曼树已成功构造完成。 \n"; } //****************************************************** voidHuffmanTree: : Encoder() { if(Node==NULL) {//内存没有哈夫曼树,则从哈夫曼树文件hfmTree.dat中读入信息并建立哈夫曼树 CreateHuffmanTreeFromFile(); if(LeafNum<=1) { cout<<"内存无哈夫曼树。 操作撤销。 \n\n"; return; } }//if char*SourceText;//字符串数组,用于存放源文 //让用户选择源文是从键盘输入,还是从源文文件ToBeTran.txt中读入 charChoose; cout<<"你要从文件中读入源文(按1),还是从键盘输入源文(按2)? "; cin>>Choose; if(Choose=='1') { ifstreamfip1("ToBeTran.txt"); if(fip1.fail()) { cout<<"源文文件打开失败! 无法继续执行。 \n"; return; } charch; intk=0; while(fip1.get(ch))k++;//第一次读文件只统计文件中有多少个字符,将字符数存入k fip1.close(); SourceText=newchar[k+1];//申请存放源文的字符数组空间 ifstreamfip2("ToBeTran.txt");//第二次读源文文件,把内容写入SourceText[] k=0; while(fip2.get(ch))SourceText[k++]=ch; fip2.close(); SourceText[k]='\0'; cout<<"需编码的源文为: "; cout< } else {//从键盘输入源文 stringSourceBuff; cin.ignore(); cout<<"请输入需要编码的源文(可输入任意长,按回车键结束): \n"; getline(cin,SourceBuff,'\n'); intk=0; while(SourceBuff[k]! ='\0') k++; SourceText=newchar[k+1]; k=0; while(SourceBuff[k]! ='\0') { SourceText[k]=SourceBuff[k]; k++; } SourceText[k]='\0'; cout<<"覆盖已有的编码原文件? (Y/N)"; charch; cin>>ch; if(ch=='y'||ch=='Y') { ofstreamfip2; fip2.open("ToBeTran.txt"); if(! fip2) { cerr<<"文件打开失败! "< abort(); } fip2< fip2.close(); cout<<"需编码的源文已写入ToBeTran.txt中"< } } //开始编码 ofstreamfop("CodeFile.dat",ios: : trunc);//打开码文存放文件 char*code; code=newchar[LeafNum];//存放一个源文字符的编码 intk=0; while(SourceText[k]! ='\0')//源文串中从第一个字符开始逐个编码 { intstar=0; charch=SourceText[k]; for(inti=0;i if(Info[i]==ch)//求出该文字所在的单元编号 break; intj=i; while(Node[j].parent! =-1) { j=Node[j].parent; if(Info[Node[j].lchild]==Info[i])code[star++]='0'; elsecode[star++]='1'; i=j; } code[star]='\0'; for(i=0;i { intj=code[i]; code[i]=code[star-i-1]; code[star-i-1]=j; } i=0;//将源文的当前字符的对应编码写入码文文件 while(code[i]! ='\0') { fop< i++; } k++;//源文串中的字符后移一个 } fop.close(); cout<<"已完成编码,码文已写入文件CodeFile.dat中。 \n\n"; } //****************************************************** voidHuffmanTree: : Decoder() { //如果内存没有哈夫曼树,则从哈夫曼树文件hfmTree.dat中读入信息并建立哈夫曼树 if(Node==NULL) { CreateHuffmanTreeFromFile(); if(LeafNum<=1) { cout<<"内存无哈夫曼树。 操作撤销。 \n\n"; return; } } //将码文从文件CodeFile.dat中读入CodeStr[] ifstreamfip1("CodeFile.dat"); if(fip1.fail()) { cout<<"没有码文,无法译码。 \n"; return; } char*CodeStr; intk=0; charch; while(fip1.get(ch)) { k++; } fip1.close(); CodeStr=newchar[k+1]; ifstreamfip2("CodeFile.dat"); k=0; while(fip2.get(ch))CodeStr[k++]=ch; fip2.close(); CodeStr[k]='\0'; cout<<"经译码得到的源文为: "; ofstreamfop("TextFile.dat"); intj=LeafNum*2-1-1;//j指向哈夫曼树的根 inti=0;//码文从第一个符号开始,顺着哈夫曼树由根下行,按码文的当前符号决定下行到左孩子还是右孩子 while(CodeStr[i]! ='\0') {//下行到哈夫曼树的叶子结点处,则译出叶子结点对应的源文字符 if(CodeStr[i]=='0')j=Node[j].lchild; elsej=Node[j].rchild; if(Node[j].rchild==-1) { cout< fop< j=LeafNum*2-1-1; } i++; } fop.close(); cout<<"\n译码成功且已存到文件TextFile.dat中。 \n\n"; } //****************************************************** voidHuffmanTree: : PrintCodeFile() { charch; inti=1; ifstreamfip("CodeFile.dat"); ofstreamfop("CodePrin.dat"); if(fip.fail()) { cout<<"没有码文文件,无法显示码文文件内容。 \n"; return; } while(fip.get(ch)) { cout< fop< if(i==50) { cout< fop< i=0; } i++; } cout< fop< fip.close(); fop.close(); } //****************************************************** voidHuffmanTree: : PrintHuffmanTree() { //如果内存没有哈夫曼树,则从哈夫曼树文件hfmTree.dat中读入信息并建立哈夫曼树 if(Node==NULL) { CreateHuffmanTreeFromFile(); if(LeafNum<=1) { cout<<"内存无哈夫曼树。 操作撤销。 \n\n"; return; } } ofstreamfop("TreePrint.dat",ios_base: : trunc); fop.close(); PrintHuffmanTree_aoru(2*LeafNum-1-1,0); return; } //****************************************************** voidHuffmanTree: : PrintHuffmanTree_aoru(intT,intlayer) { for(inti=0;i cout< if(Node[T].lchild! =-1)PrintHuffmanTree_aoru(Node[T].lchild,++layer); if(Node[T].rchild! =-1)PrintHuffmanTree_aoru(Node[T].rchild,layer--); } ///////////////////////////////////////////////////////////////////main.cpp #include #include usingnamespacestd; intmain() { HuffmanTreehuftree; charChoose; while (1) { cout<<"\n\n**********************欢迎使用哈夫曼编码/译码系统***********************"< cout<<"您可以进行以下操作: "< cout<<"1建立哈夫曼树3译码(码文已在文件CodeFile中)5显示哈夫曼树"< cout<<"2编码(源文已在文件ToBeTran中,或键盘输入)4显示码文6退出"< cout<<"请选择一个操作: "; cin>>Choose; switch(Choose) { case'1': huftree.CreateHuffmanTree(); break; case'2': huftree.Encoder(); break; case'3': huftree.Decoder(); break; case'4': huftree.PrintCodeFile(); break; case'5': huftree.PrintHuffmanTree(); break; case'6': cout<<"\n*************************感谢使用本系统! **************
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 哈夫曼树 编码 译码 实验 报告