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

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

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

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

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

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

【具体设计】之杨若古兰创作

具体代码实现如下:

#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()调用*/

};

#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'

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";

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)

CreateHuffmanTreeFromFile();

if(LeafNum<=1)

{

cout<<"内存无哈夫曼树.操纵撤消.\n\n";

return;

}

}//if

char*SourceText;//字符串数组,用于存放源文

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()

{

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()

{

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--);

}

#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*************************感谢使用本零碎!

***********************\n\n";

system("pause");

return0;

}//switch

}//while

}//main

【用户手册】

进入哈弗曼树零碎,出现以下界面:

1建立弗曼树2、编码(源文中读入,键盘输入)3、译码4、显示码文5、显示哈弗曼树6、退出

用户根据该提示,选择前面数字,就能进入各个功能函数,实现函数功能.

【运转结果】截图一:

截图二:

截图三:

截图四:

【心得体会】

本实验是搜集相干材料,然后本人添加功能函数的代码实现的.是以,在完成未完成的功能函数之前还必必要仔细浏览所给出代码,全体观察各个部分之前的联系,搞清楚已给出和未完成的代码功能以后,才根据算法,设计出该功能的函数代码.

在完成实验时,有发古代码也有纰漏的地方,如在源文件读入的时候,多出了一个值,得要添加下表减这个代码来去掉.还有就是在译码的时候,因为变量定义的混淆,在编译的时候通过,但履行时却出现料想不到的结果,在本人仔细观察、思考之前也还没找出错误的地方.后来通过请教老师,在和老师讨论检查以后才晓得了错误之所在,最初改正错误.实验成功完成.

【参考文献】

数据结构与算法(课本)

C++说话基础

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

当前位置:首页 > 求职职场 > 简历

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

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