数据结构哈夫曼树编码译码实验报告.docx

上传人:b****8 文档编号:30385067 上传时间:2023-08-14 格式:DOCX 页数:26 大小:225.49KB
下载 相关 举报
数据结构哈夫曼树编码译码实验报告.docx_第1页
第1页 / 共26页
数据结构哈夫曼树编码译码实验报告.docx_第2页
第2页 / 共26页
数据结构哈夫曼树编码译码实验报告.docx_第3页
第3页 / 共26页
数据结构哈夫曼树编码译码实验报告.docx_第4页
第4页 / 共26页
数据结构哈夫曼树编码译码实验报告.docx_第5页
第5页 / 共26页
点击查看更多>>
下载资源
资源描述

数据结构哈夫曼树编码译码实验报告.docx

《数据结构哈夫曼树编码译码实验报告.docx》由会员分享,可在线阅读,更多相关《数据结构哈夫曼树编码译码实验报告.docx(26页珍藏版)》请在冰豆网上搜索。

数据结构哈夫曼树编码译码实验报告.docx

数据结构哈夫曼树编码译码实验报告

【详细设计】

具体代码实现如下:

//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*************************感谢使用本系统!

**************

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 教育学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1