c++哈夫曼树的文件压缩解压程序全部代码及设计报告.pdf
《c++哈夫曼树的文件压缩解压程序全部代码及设计报告.pdf》由会员分享,可在线阅读,更多相关《c++哈夫曼树的文件压缩解压程序全部代码及设计报告.pdf(44页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、#include#include#include /队列容器using namespace std;const int leaf=256;/最多可能出现的不同字符数const long MAX=99999999;/表示无穷大typedef struct HTnodelong weight;/记录结点的权值int parent;/记录结点的双亲结点位置int lchild;/结点的左孩子int rchild;/结点的右孩子int*code;/记录该结点的 huffman 编码int codelen;/记录该结点 huffman 编码的长度HTnode()weight=MAX;parent=-1;
2、lchild=-1;rchild=-1;codelen=0;HTnode;class huffmanTreepublic:huffmanTree();virtual huffmanTree();bool count(char*input);/统计各字符出现的次数,将其写入对应结点的权值void create();/构造 huffman 树void code();/计算每个字符的 huffman 编码void addbit(int bit);/压缩时对一个未满 8 个 bit 的 byte 中加入一个 bitvoid resetbyte();/将 byte 清空bool compress(cha
3、r*input,char*output);/压缩函数 成功执行返回 true 失败 falsebool decompress(char*input,char*output);/解压函数 成功执行返回 true失败 falsevoid compare(char*input,char*output);/将原文件与压缩后的文件比较private:int root;/记录根结点的位置int leafnum;/记录不同字符的个数HTnode HTleaf*2-1;点个数不会超过 leaf*2-1char byte;int bitsnum;int lacknum;huffmanTree:huffmanTr
4、ee()/HTnode 结构的数组,用来表示 huffman 树,树的最大结/压缩文件时用来缓冲 bit 的变量/byte 中 bit 的个数/压缩到最后 byte 中的 bit 不满 8 个时填充的 0 的个数/初始化成员变量root=0;leafnum=0;byte=0;bitsnum=0;lacknum=0;huffmanTree:huffmanTree()for(int i=0;ileaf;i+)if(HTi.codelen!=0)delete HTi.code;/统计各字符出现的次数bool huffmanTree:count(char*input)ifstream ifs;char
5、 c;ifs.open(input,ios:binary);if(!ifs)cout 无法打开文件 input !endl;return false;while(ifs.get(c)if(HTc+128.weight=MAX)/若该字符是第一次出现,先初始化权值HTc+128.weight=0;leafnum+;HTc+128.weight+;/权值+1ifs.close();return true;/选权值最小的两棵树组成新的数void huffmanTree:create()for(int i=leaf;i2*leaf-1;i+)int loc1=-1,loc2=-1;for(int j=
6、0;ji;j+)if(HTj.parent!=-1)continue;if(loc1=-1|HTj.weight HTloc1.weight)loc2=loc1;loc1=j;else if(loc2=-1|HTj.weight loc2?loc2:loc1;HTi.rchild=loc1loc2?loc1:loc2;HTloc1.parent=i;HTloc2.parent=i;root=i;/计算每个字符的 huffman 编码void huffmanTree:code()for(int i=0;i=0;j-)/从后往前找,记录结点的huffman 编码if(loc=HTHTloc.par
7、ent.lchild)HTi.codej=0;elseHTi.codej=1;loc=HTloc.parent;/压缩时对一个未满 8 个 bit 的 byte 中加入一个 bitvoid huffmanTree:addbit(int bit)if(bit=0)byte=byte 1;/若新增的 bit 为 0,则直接将 byte 按位左移elsebyte=(byte 1)|1);/若新增的 bit 为 1,先将 byte 按位左移,再与 1 按位或运算bitsnum+;/将 byte 清空void huffmanTree:resetbyte()byte=0;bitsnum=0;/压缩函数 成
8、功执行返回 true 失败 falsebool huffmanTree:compress(char*input,char*output)if(!count(input)return false;create();code();ifstream ifs;ofstream ofs;ifs.open(input,ios:binary);ofs.open(output,ios:binary);char c;if(!ifs)cout 无法打开文件 input !endl;return false;if(!ofs)cout 无法打开文件 output !endl;return false;ofs.put(
9、0);/预留一个字符,等压缩完后在该位置写入不足一个byte 的 bit 个数ofs.put(root-384);/将根节点的位置-384 写入(为使该值不超过char 的最大表示范围)for(int i=0;ileaf*2-1;i+)/写入每个结点的双亲结点位置if(HTi.parent=-1)/若该节点没有双亲结点,则写入 127(一个字节所能表示的最大ofs.put(127);值)else/否则将双亲结点的位置-384 再写入(为使该值不超过char 的最大表示范围)ofs.put(HTi.parent-384);while(ifs.get(c)/将字符的 huffman 编码并加入 b
10、yte 中int tmp=c+128;for(int i=0;iHTtmp.codelen;i+)addbit(HTtmp.codei);if(bitsnum=8)/若 byte 已满 8 位,则输出该 byte 并将 byte 清空ofs.put(byte);resetbyte();if(bitsnum!=0)/处理最后未满 8 个字符的 byte,用 0 填充并记录填充的个数for(int i=bitsnum;i8;i+)addbit(0);lacknum+;ofs.put(byte);resetbyte();ofs.seekp(0,ios:beg);ofs.put(lacknum);if
11、s.close();ofs.close();return true;/将写指针移动到文件开头/写入最后一个字节缺失的bit 个数/解压函数 成功执行返回 true 失败 falsebool huffmanTree:decompress(char*input,char*output)queue q;char c;ifstream ifs;ofstream ofs;ifs.open(input,ios:binary);ofs.open(output,ios:binary);if(!ifs)cout 无法打开文件 input !endl;return true;if(!ofs)cout 无法打开文件
12、 output !endl;return false;ifs.get(c);lacknum=c;/读出最后一个字节缺失的bit 个数ifs.get(c);root=c+384;/读出根结点的位置for(int i=0;i1)/还未到最后一个字节c=q.front();for(int i=0;i8;i+)if(int(c&128)=0)point=HTpoint.lchild;if(HTpoint.lchild=-1&HTpoint.rchild=-1)ofs.put(char(point-128);point=root;c=c 1;elsepoint=HTpoint.rchild;if(HTp
13、oint.lchild=-1&HTpoint.rchild=-1)ofs.put(char(point-128);point=root;c=c 1;q.pop();c=q.front();/最后一个字节for(i=0;i8-lacknum;i+)if(int(c&128)=0)point=HTpoint.lchild;if(HTpoint.lchild=-1&HTpoint.rchild=-1)ofs.put(char(point-128);point=root;c=c 1;elsepoint=HTpoint.rchild;if(HTpoint.lchild=-1&HTpoint.rchild
14、=-1)ofs.put(char(point-128);point=root;c=c 1;q.pop();ifs.close();ofs.close();return true;/将原文件与压缩后的文件比较void huffmanTree:compare(char*input,char*output)ifstream origin,compress;origin.open(input,ios:binary);compress.open(output,ios:binary);if(!origin)cout 无法打开文件 input !endl;return;if(!compress)cout 无
15、法打开文件 output !endl;return;double total1=0,total2=0;char c;while(origin.get(c)total1+;while(compress.get(c)total2+;cout 原文件大小:total1 Byte endl;cout 压缩后大小:total2 Byte endl;cout 压缩率:total2/total1*100%endl;origin.close();compress.close();void main()int choice=1;char input255,output255;huffmanTree h;whil
16、e(choice)cout*endl;coutcoutcoutcoutcoutcoutcoutcout*基于哈夫曼树的文件压缩/解压程序*endl;*endl;*1)压缩*endl;*endl;*2)解压*endl;*endl;*0)退出*endl;*endl;cout*说明:请输入相应的操作序号*endl;cout*endl;cout choice;switch(choice)case 1:cout input;cout output;if(press(input,output)pare(input,output);cout文件压缩成功!endl;elsecout文件压缩失败!endl;br
17、eak;case 2:cout input;cout output;if(h.decompress(input,output)cout文件解压成功!endl;elsecout文件解压失败!endl;break;case 0:break;default:cout 参数错误!请重新输入 endl;cout endl;韶关学院计算机科学学院数据结构课程设计题题目:基于哈夫曼树的文件压缩目:基于哈夫曼树的文件压缩/解压程序解压程序学生姓名:曹键明学生姓名:曹键明学学号:号:1111501101811115011018专专业:计算机科学与技术业:计算机科学与技术班班级:级:1111 级(级(1 1)班)
18、班指导教师姓名及职称:陈正铭指导教师姓名及职称:陈正铭讲师讲师起止时间:起止时间:2013 年 3 月 2013 年 4 月1 1 需求分析需求分析1.1 课题背景及意义近年来,随着计算机技术的发展,多媒体计算机技术、计算机网络技术以及现代多媒体通信技术正在向着信息化、高速化、智能化迅速发展。各个领域的应用与发展,各个系统的数据量越来越大,给数据的存储、传输以及有效、快速获取信息带来了严重的障碍。数据压缩技术能够比较有效地解决这个问题。还有在最近几年中兴起的物联网和云计算都是对海量的数据进行处理和传输的,如果不对数据进行压缩,那么数据传输所需的带宽要求就很高,物理成本上也随之上升。所以说数据压
19、缩在计算机通信中占有很重要的位置,且涉及领域多,应用广泛,与我们的生活息息相关。1.2 课题要求1.2.1实现一个基于哈夫曼树的文件压缩程序和文件解压程序。1.2.2.压缩程序能输入源文件进行压缩,输出压缩文件;1.2.3解压程序读入压缩文件,根据相应的哈夫曼编码解压还原,得到对应的源文件。1.2.4可选做:求出压缩率;打印哈夫曼树;对文件夹压缩;图形图形化窗口操作界面。1.3 任务和要求1.3.1 选择 1 时:输入一个待压缩的文本文件名称(可带路径)。如:D:1XXX.txt压缩文件名称=D:1YYY.txt1.3.2 选择 2 时:输入一个待解压的压缩文件名称(可带路径)。如:D:1YY
20、Y.txt解压文件名称=D:XXX.txt2 2 概要设计概要设计2.1 问题解决的思路概述统计字符,得出统计出字符的权值n生成哈夫曼树建立哈夫曼树根据哈夫曼树编码对编码进行压缩根据哈夫曼树解码对二进制文件进行解码生成二进制文件生成对应文件图 1 主程序流程图2.2 算法思想:2.2.1 输入要压缩的文件首先运行的时候,用户主界面上有菜单提示该如何使用软件,根据菜单提示选择所要执行的项,依次进行,因为各个环节之间有先后顺序。第一步为输入压缩软件的名称,由键盘输入文件路径和文件名称,读入字符数组中,打开该文件,按照提示进行压缩。若打不开,则继续输入。2.2.2 读文件并计算字符频率文件将信息存放
21、在字符数组中;计算每个字符出现的次数,申请一个结构体数组空间,用读取的字符减去字符结束符作为下标记录字符的频率。2.2.3 根据字符的频率,利用 Huffman 编码思想创建 Huffman 树将所记录的字符的频率作为权值来创建 Huffman 树,依次选择权值最小的两个字符作为左右孩子,其和作为父结点的权值,依次进行下去,直到所有的字符结点都成为叶子结点。2.2.4 由创建的 Huffman 树来决定字符对应的编码,进行文件的压缩根据创建的 Huffman 树来确定个字符的 01 编码,左孩子为 0,右孩子为1。读取文件,依次将每个字符用他们的编码表示,即完成一次编码。2.2.5 解码压缩即
22、根据 Huffman 树进行译码读取编码文件,依据创建的Huffman 树,定义一个指针指向根结点。从根结点开始,每读一个字符,指针变化一次(当读取的字符是1时,指针指向当前所指结点的右孩子,当读取的字符是0时,指针指向当前所指结点的左孩子),直至该指针所指结点为叶子结点时结束(即当结点的左右孩子均为空时)。将当前叶子结点所代表的字符值输出到译码文件中,依次读取编码文件中的字符,按照上述方法依次进行下去直至文件2.3 数据结构定义/huffman树的结点结构体typedef struct HTnodelong weight;/记录结点的权值int parent;/记录结点的双亲结点位置int
23、lchild;/结点的左孩子int rchild;/结点的右孩子int*code;/记录该结点的huffman编码int codelen;/记录该结点huffman编码的长度HTnode()weight=MAX;parent=-1;lchild=-1;rchild=-1;codelen=0;HTnode;2.4 定义 huffman 数类及其函数class huffmanTreepublic:huffmanTree();virtual huffmanTree();bool count(char*input);/压缩时统计各字符出现的次数,将其写入对应结点的权值void create();/压缩
24、时根据各结点的权值构造 huffman树void code();/压缩时利用huffman树计算每个字符的huffman编码void addbit(int bit);/压缩时对一个未满8个bit的byte中加入一个bitvoid resetbyte();/将byte清空bool compress(char*input,char*output);/压缩函数,成功返回 true失败 falsebool decompress(char*input,char*output);/解压函数,成功返回true 失败falsevoid compare(char*input,char*output);/将原文件
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- c+ 哈夫曼树 文件 压缩 解压 程序 全部 代码 设计 报告
限制150内