哈夫曼树编码实验报告材料Word格式.docx
- 文档编号:17241979
- 上传时间:2022-11-29
- 格式:DOCX
- 页数:20
- 大小:190.53KB
哈夫曼树编码实验报告材料Word格式.docx
《哈夫曼树编码实验报告材料Word格式.docx》由会员分享,可在线阅读,更多相关《哈夫曼树编码实验报告材料Word格式.docx(20页珍藏版)》请在冰豆网上搜索。
六、源程序
1.程序的功能;
哈夫曼编码是一种应用广泛而有效的数据压缩技术。
利用哈夫曼编码进行通信可以大大提高信道利用率,加快信息传输速度,降低传输成本。
数据压缩的过程称为编码,解压缩的过程称为译码。
进行信息传递时,发送端通过一个编码系统对待传数据(明文)预先编码,而接收端将传来的数据(密文)进行译码。
2.输入输出的要求;
:
2.1.构造哈夫曼树及哈夫曼编码:
从终端读入字符集大小n、n个字符以及n个对应的权值,建立哈夫曼树;
利用已经建好的哈夫曼树求每个叶结点的哈夫曼编码,并保存。
2.2编码:
利用已构造的哈夫曼编码对“明文”文件中的正文进行编码,然后将结果存入“密文”文件中。
2.3.译码:
将“密文”文件中的0、1代码序列进行译码。
2.4.打印“密文”文件:
将文件以紧凑格式显示在终端上,每行30个代码;
同时,将此字符形式的编码文件保存。
2.5.打印哈夫曼树及哈夫曼编码:
将已在内存中的哈夫曼树以凹入表形式显示在终端上,同时将每个字符的哈夫曼编码显示出来;
并保存到文件。
3.测试数据。
3.1.令叶子结点个数N为4,权值集合为{1,3,5,7},字符集合为{A,B,C,D},且字符集与权值集合一一对应。
3.2.请自行选定一段英文文本,统计给出的字符集,实际统计字符的频度,建立哈夫曼树,构造哈夫曼编码,并实现其编码和译码。
1.本程序所用的抽象数据类型的定义;
classHuffmanTree//哈夫曼树
{
private:
HuffmanNode*Node;
//Node[]存放哈夫曼树
intLeafNum;
//哈夫曼树的叶子个数,也是源码个数
2.主程序模块
main()
2.2建立哈夫曼树函数
//函数功能:
建立哈夫曼树
voidHuffmanTree:
:
CreateHuffmanTree()
2.3函数功能:
为哈夫曼树编码
Encoder()
2.4函数功能:
对哈夫曼树进行译码
Decoder()
2.5输出码文函数
从文件中输出哈夫曼树的码文
PrintCodeFile()
2.6函数功能:
用凹入法输出哈夫曼树
PrintHuffmanTree_aoru(intT,intlayer)
3.主模块的流程及各子模块的主要功能;
基本功能分析
4.模块之间的层次关系。
①初始化:
从键盘接收字符集大小n,以及n个字符和n个权值。
②建立哈夫曼树:
构造哈夫曼树,即将HNode数组中的各个位置的各个域都添上相关的值,并将这个结构体数组存于文件HTree.txt中。
③构造哈夫曼编码:
为从文件HTree.txt中读入相关的字符信息进行哈夫曼编码,然后将结果存入HNode.txt中,同时将字符与0、1代码串的一一对应关系打印到屏幕上。
④编码:
利用已构造的哈夫曼编码(HNode.txt)对文件SourceFile.txt(明文)中的正文进行编码,然后将结果存入文件CodeFile.txt(密文)中。
⑤译码:
将文件CodeFile.txt(密文)中的代码按照③中建立的编码规则将其翻译成字符集中字符所组成的字符串形式,进行译码,结果存入文件TextFile.txt(明文)中。
(如果正确,TextFile.txt的内容与SourceFile.txt的内容一致)
⑥显示哈夫曼树:
从HNode数组中读入相关的结点信息,以凹入表方式将各个结点以及叶子结点的权值和左分支上的0和右分支上的
1.采用c语言定义相关的数据类型;
结点的类型定义描述如下:
structHuffmanNode//哈夫曼树的一个结点
intweight;
intparent;
intlchild,rchild;
charsourcecode;
std:
stringcode;
};
2.伪码算法
public:
HuffmanTree();
~HuffmanTree();
voidCreateHuffmanTree();
voidCreateHuffmanTreeFromKeyboard();
voidCreateHuffmanTreeFromFile();
voidEncoder();
voidDecoder();
voidPrintCodeFile();
voidPrintHuffmanTree();
voidPrintHuffmanTree_aoru(intT,intlayer=1);
//构造函数
初始化哈夫曼树
HuffmanTree:
HuffmanTree()
Node=NULL;
LeafNum=0;
}
将哈夫曼的数组的空间释放
//参数返回值:
无
~HuffmanTree()
delete[]Node;
//建立哈夫曼树函数
charChoose;
cout<
<
"
从键盘输入哈夫曼树(按2)?
;
cin>
>
Choose;
if(Choose=='
2'
){
CreateHuffmanTreeFromKeyboard();
}//choose=='
else{//从哈夫曼树文件hfmTree.dat中读入信息并建立哈夫曼树
CreateHuffmanTreeFromFile();
}
从键盘建立哈夫曼树
CreateHuffmanTreeFromKeyboard(){
intNum;
\n请输入源码字符集个数:
Num;
if(Num<
=1){
无法建立少于2个叶子结点的哈夫曼树。
\n\n"
return;
LeafNum=Num;
Node=newHuffmanNode[2*Num-1];
for(inti=0;
i<
i++){//读入哈夫曼树的叶子结点信息
请输入第"
i+1<
个字符值"
getchar();
Node[i].sourcecode=getchar();
//源文的字符存入字符数组Info[]
请输入该字符的权值"
Node[i].weight;
//源文的字符权重存入Node[].weight
Node[i].parent=-1;
Node[i].lchild=-1;
Node[i].rchild=-1;
Node[i].code="
\0"
for(intj=Num;
j<
2*Num-1;
j++){//循环建立哈夫曼树内部结点
intpos1,pos2;
intmax1,max2;
pos2=pos1=j;
max2=max1=numeric_limits<
int>
max();
//在所有子树的根结点中,选权重最小的两个根结点,pos1最后应指向权重最小的根结点的下标
for(intk=j-1;
k>
=0;
k--){
if(Node[k].parent==-1){//如果是某棵子树的根结点
if(Node[k].weight<
max1){//发现比当前最大值还大的权重
max2=max1;
max1=Node[k].weight;
pos2=pos1;
pos1=k;
else
if(Node[k].weight<
max2){//发现比当前次大值还大的次大权重
max2=Node[k].weight;
pos2=k;
}//if(Node[j].parent==-1)
}//for
//在下标i处新构造一个哈夫曼树的内部结点,其左、右孩子就是以上pos1、pos2所指向的结点
Node[pos1].parent=j;
Node[pos2].parent=j;
Node[j].lchild=pos1;
Node[j].rchild=pos2;
Node[j].parent=-1;
Node[j].weight=Node[pos1].weight+Node[pos2].weight;
//产生所有叶子结点中字符的编码
for(intm=0;
m<
m++){
//产生Node[i].sourcecode的编码,存入Node[i].code中
intj=m;
intj1;
while(Node[j].parent!
=-1){//从叶结点开始往根结点走,每往上走一层,就产生一位编码存入code[]
j1=Node[j].parent;
if(Node[j1].lchild==j)
Node[m].code.insert(0,"
0"
);
else
1"
j=j1;
cout<
哈夫曼树已成功构造完成。
\n"
charch;
是否要替换原来的哈夫曼树文件(Y/N):
ch;
if(ch!
='
y'
&
ch!
Y'
)return;
ofstreamfop;
fop.open("
hfmTree.dat"
ios:
out|ios:
binary|ios:
trunc);
//打开文件
if(fop.fail()){
\n哈夫曼树文件打开失败,无法将哈夫曼树写入hfmTree.dat文件。
fop.write((char*)&
Num,sizeof(Num));
//先写入哈夫曼树的叶子结点个数
for(intn=0;
n<
n++){//最后写入哈夫曼树的各个结点(存储在Node[]中)
Node[n],sizeof(Node[n]));
flush(cout);
fop.close();
//关闭文件
\n哈夫曼树已成功写入hfmTree.dat文件。
//从文件建立哈夫曼树函数
从文件建立哈夫曼树
CreateHuffmanTreeFromFile(){
ifstreamfip;
fip.open("
in);
if(fip.fail()){
哈夫曼树文件hfmTree.dat打开失败,无法建立哈夫曼树。
fip.read((char*)&
LeafNum,sizeof(LeafNum));
if(LeafNum<
哈夫曼树文件中的数据有误,叶子结点个数少于2个,无法建立哈夫曼树。
fip.close();
Node=newHuffmanNode[2*LeafNum-1];
2*LeafNum-1;
i++)
Node[i],sizeof(Node[i]));
哈夫曼树已从文件成功构造完成。
//编码函数
if(Node==NULL){//内存没有哈夫曼树,则从哈夫曼树文件hfmTree.dat中读入信息并建立哈夫曼树
内存无哈夫曼树。
操作撤销。
}//if
char*SourceText;
//让用户选择源文是从键盘输入,还是从源文文件ToBeTran.txt中读入
从键盘输入源文(按2)?
1'
){
ifstreamfip1("
ToBeTran.txt"
if(fip1.fail()){
源文文件打开失败!
无法继续执行。
intk=0;
while(fip1.get(ch))k++;
fip1.close();
SourceText=newchar[k+1];
ifstreamfip2("
k=0;
while(fip2.get(ch))SourceText[k++]=ch;
fip2.close();
SourceText[k]='
\0'
else{
stringSourceBuff;
cin.ignore();
请输入需要编码的源文(按回车键结束):
getline(cin,SourceBuff,'
\n'
while(SourceBuff[k]!
)
k++;
SourceText[k]=SourceBuff[k];
需编码的源文为:
SourceText<
endl;
ofstreamfop("
CodeFile.dat"
//打开码文存放文件
while(SourceText[k]!
)//源文串中从第一个字符开始逐个编码
{
inti;
for(i=0;
LeafNum;
i++){//找到当前要编码的源文的字符在哈夫曼树Node[]中的下标
if(Node[i].sourcecode==SourceText[k]){//将对应编码写入码文文件
fop<
Node[i].code;
break;
};
if(i>
=LeafNum){
源文中存在不可编码的字符。
k++;
已完成编码,码文已写入文件CodeFile.dat中。
//如果内存没有哈夫曼树,则从哈夫曼树文件hfmTree.dat中读入信息并建立哈夫曼树
if(Node==NULL)
没有码文,无法译码。
char*CodeStr;
while(fip1.get(ch)){
CodeStr=newchar[k+1];
while(fip2.get(ch))
CodeStr[k++]=ch;
CodeStr[k]='
经译码得到的源文为:
TextFile.dat"
intj=LeafNum*2-1-1;
inti=0;
while(CodeStr[i]!
){//下行到哈夫曼树的叶子结点处,则译出叶子结点对应的源文字符
if(CodeStr[i]=='
0'
j=Node[j].lchild;
j=Node[j].rchild;
if(Node[j].rchild==-1){//因为哈夫曼树没有度为1的结点,所以此条件等同于Node[j]为叶结点
Node[j].sourcecode;
j=LeafNum*2-1-1;
i++;
\n译码成功且已存到文件TextFile.dat中。
//输出码文函数
inti=1;
ifstreamfip("
CodePrin.dat"
if(fip.fail())
没有码文文件,无法显示码文文件内容。
while(fip.get(ch))
if(i==50)
i=0;
//输出函数
从内存或文件中直接输出哈夫曼树
PrintHuffmanTree()
ofstreamfop("
TreePrint.dat"
ios_base:
PrintHuffmanTree_aoru(2*LeafNum-1-1);
//凹入法输出函数
PrintHuffmanTree_aoru(intT,intlayer){
if(T!
=-1){
PrintHuffmanTree_aoru(Node[T].lchild,layer+1);
app);
for(inti=0;
layer*5;
i++){
"
if(Node[T].lchild==-1){
Node[T].sourcecode<
Node[T].weight<
("
Node[T].code<
)"
No
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 哈夫曼树 编码 实验 报告 材料
![提示](https://static.bdocx.com/images/bang_tan.gif)