数据结构哈夫曼编码实验报告.docx
- 文档编号:5685924
- 上传时间:2022-12-31
- 格式:DOCX
- 页数:9
- 大小:123.48KB
数据结构哈夫曼编码实验报告.docx
《数据结构哈夫曼编码实验报告.docx》由会员分享,可在线阅读,更多相关《数据结构哈夫曼编码实验报告.docx(9页珍藏版)》请在冰豆网上搜索。
数据结构哈夫曼编码实验报告
实验报告
实验课名称:
数据结构实验
实验名称:
文件压缩问题
班级:
20132012
学号:
:
时间:
2015-6-9
一、问题描述
哈夫曼编码是一种常用的数据压缩技术,对数据文件进行哈夫曼编码可大大缩短文件的传输长度,提高信道利用率及传输效率。
要求采用哈夫曼编码原理,统计文本文件中字符出现的词频,以词频作为权值,对文件进行哈夫曼编码以达到压缩文件的目的,再用哈夫曼编码进行译码解压缩。
二、数据结构设计
首先定义一个结构体:
structhead
{
unsignedcharb;//记录字符
longcount;//权重
intparent,lch,rch;//定义双亲,左孩子,右孩子
charbits[256];//存放哈夫曼编码的数组
}
header[512],tmp;//头部一要定设置至少512个,因为结点最多可达256,所有结点数最多可达511
三、算法设计
输入要压缩的文件读文件并计算字符频率根据字符的频率,利用Huffman编码思想创建Huffman树由创建的Huffman树来决定字符对应的编码,进行文件的压缩解码压缩即根据Huffman树进行译码
设计流程图如图1.1所示。
图1.1设计流程图
(1)压缩文件
输入一个待压缩的文本文件名称(可带路径)如:
D:
\lu\lu.txt统计文本文件中各字符的个数作为权值,生成哈夫曼树;将文本文件利用哈夫曼树进行编码,生成压缩文件。
压缩文件名称=文本文件名.COD如:
D:
\lu\lu.COD压缩文件内容=哈夫曼树的核心内容+编码序列
for(inti=0;i<256;i++)
{
header[i].count=0;//初始化权重
header[i].b=(unsignedchar)i;//初始化字符
}
ifstreaminfile(infilename,ios:
:
in|ios:
:
binary);
while(infile.peek()!
=EOF)
{
infile.read((char*)&temp,sizeof(unsignedchar));//读入一个字符
header[temp].count++;//统计对应结点字符权重
flength++;//统计文件长度
}
infile.close();//关闭文件
for(i=0;i<256-1;i++)//对结点进行冒泡排序,权重大的放在上面,编码时效率高
for(intj=0;j<256-1-i;j++)
if(header[j].count { tmp=header[j]; header[j]=header[j+1]; header[j+1]=tmp; } for(i=0;i<256;i++) if(header[i].count==0)break; leafnum=i;//取得哈夫曼树中叶子结点数 pointnum=2*leafnum-1;//取得哈夫曼树中总结点数目 infile.open(infilename,ios: : in|ios: : binary);//打开待压缩的文件 infile.clear(); infile.seekg(0); ofstreamoutfile(outfilename,ios: : out|ios: : binary);//打开压缩后将生成的文件 outfile.write((char*)&flength,sizeof(long));//写入原文件长度 (2)哈夫曼编码 for(i=0;i { outfile.write((char*)&header[i].b,sizeof(unsignedchar));//写入字符 header[i].count=strlen(header[i].bits);//不再设置其他变量,权值这时已无使用价值,可以用相应结点的权值变量记录长度 outfile.write((char*)&header[i].count,sizeof(unsignedchar));//写入长度的ASCII码 if(header[i].count%8==0) bytelen=header[i].count/8; else { bytelen=header[i].count/8+1; strcat(header[i].bits,"0000000");//在编码后面补0,使其最后凑满8的倍数, //超过无妨,可以用bytelen控制好写入字节的长度 } for(intj=0;j { temp=ctoa(header[i].bits); outfile.write((char*)&temp,sizeof(unsignedchar)); strcpy(header[i].bits,header[i].bits+8); cout<<"该文件的哈夫曼的编码为: "< for(i=0;i { cout< } } }//此循环结束后就完成了编码对照表的写入 (3)解压文件 输入一个待解压的压缩文件名称(可带路径)如: D: \lu\lu.COD从文件中读出哈夫曼树,并利用哈夫曼树将编码序列解码;生成(还原)文本文件。 文件文件名称=压缩文件名+"_new.txt"如: D: \lu\lu_new.txt while (1) { while(readlen<(clength-8)&&strlen(buf)<=256)//读满缓冲区 { infile.read((char*)&temp,sizeof(temp)); ctoa(temp,code);//将字节转为数组 strcat(buf,code); readlen++; }//while while(strlen(buf)>=256)//处理缓冲区,直到少于256位,再读满它 { for(i=0;i { strcpy1(buf1,buf,i+1);//逐渐增多取,放入buf1,进行匹配 if(strcmp1(buf1,header,n,temp)==1) { outfile.write((char*)&temp,sizeof(unsignedchar)); writelen++; strcpy(buf,buf+i+1);//缓冲区前移 break; } }//for if(writelen>=flength)break;//如果写入达到原文件长度,退出 }//while if(readlen>=(clength-8)/*编码长度*/||writelen>=flength)break;//如果写入或者读入编码完毕,退出 }//退出此循环后,还有未解码完成的buf[] //对buf[]缓冲的善后处理 while(writelen { for(i=0;i { strcpy1(buf1,buf,i+1); if(strcmp1(buf1,header,n,temp)==1) { outfile.write((char*)&temp,sizeof(unsignedchar)); writelen++; strcpy(buf,buf+i+1); break; } }//for } infile.close();//关闭文件 outfile.close(); 四、界面设计 程序包含压缩功能,解压功能,输出功能,帮助,终止程序功能。 五、运行测试与分析 (1)运行程序,显示提示,如图1.2所示。 图1.2启动界面 (2)编码操作。 图1.3在D盘中建立一个文本文档,并命名为123.txt 图1.4文件压缩,输出哈弗曼编码界面 图1.5在D盘中生成一个.COD的文档,并且名为12.COD: (3)解码操作。 根据实验要求输出实验结果。 如图1.4所示。 图1.4数据结果输出界面 (4)显示数据内容 若用户想知道文本输入的内容,可输入“L”,然后界面提示输入文本文件的路径和文件名,完成输入后按回车键,界面会出现文本的内容。 六、实验收获与思考 在完成实验的过程中,使我明白了面向对象与面向对象的差别。 在面向对象过程中,类的设计是至关重要的,类设计好了等于程序就成功了一半,所以这次的课程帮助我复习了这一学期面向对象课程的学习,刚好可以弥补这一学期面向对象学习的不足。 同时,也使我对数据结构与算法的知识有了一定的了解,帮我在大二学习数据结构与算法的课程中奠定了一定的基础,使我以后学习数据结构与算法的时候可以更加轻松。 教师评分: 教师签字:
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 哈夫曼 编码 实验 报告
![提示](https://static.bdocx.com/images/bang_tan.gif)