Huffman压缩试验报告汇总Word文档下载推荐.docx
- 文档编号:20981506
- 上传时间:2023-01-26
- 格式:DOCX
- 页数:23
- 大小:136.42KB
Huffman压缩试验报告汇总Word文档下载推荐.docx
《Huffman压缩试验报告汇总Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《Huffman压缩试验报告汇总Word文档下载推荐.docx(23页珍藏版)》请在冰豆网上搜索。
a)这里的Huffman树采用的是基于数组的带左右儿子结点及父结点下标作为存储结点的二叉树形式,这种空间上的消耗带来了算法实现上的便捷。
b)将各个字符的编码存储在一个数组charCodes中,为了能快速找到一个字符的编码,用函数(*CharIndex)来实现字符位置的映射,使用先序遍历二叉树的方法来求各个字符的编码方案。
c)采用小顶堆的方式来存储各个二叉树的根,实际是存储指向根结点的指针。
(2)压缩过程的实现
压缩过程的流程是清晰而简单的:
1创建Huffman树→2打开需压缩文件→3将需压缩文件中的每个ASCII码对应的Huffman编码按bit单位输出→4文件压缩结束。
其中,步骤1和步骤3是压缩过程的关键。
a)步骤1:
这里所要做工作是得到Huffman数中各叶子结点字符出现的频率并进行创建。
b)步骤3:
将需压缩文件中的每个ASCII码对应的Huffman编码按bit单位输出,这是本压缩程序中最关键的部分。
需定义一个字符缓存器BufferType,以便自动将比特转化为字节。
structBufferType
{charch;
unsignedintbits;
};
(3)解压过程类似压缩过程的实现
(4)输出部分
1)每个字符所对应的HuffmanCode的比特位长度不等长,不可少输,
多输,输错任何一位,后一个字符的HuffmanCode要紧跟在前一个字符的HuffmanCode后面。
2)最后一个要输出的HuffmanCode的最后一位,它恰好是位于最后一个有效字符的第一位,剩下的七个空位是要用无效的HuffmanCode加以填充。
否则,如果填充的HuffmanCode亦为某个ascii字符的HuffmanCode时,那么在解压缩时,则该在原被压缩文件中不存在的字符便会无中生有的在解压后的文件中出现,这显然是不正确的,应在程序中加以处理。
(5)main函数部分
N
Y
N
3.代码实现
Huffman树结点的抽象基类模板
类型
成员
功能
virtualWeightTypeWeight()=0
返回权值
virtualboolIsLeaf()=0
判断结点是否为叶子节点
virtualMyHuffmanNode<
CharType,WeightType>
*Left()=0
返回结点的左孩子
函
数
模
板
*Right()=0
返回结点的右孩子
virtualvoidSetLeft(MyHuffmanNode<
*child)=0
设置结点的左孩子
virtualvoidSetRight(MyHuffmanNode<
设置结点的右孩子
Huffman树叶子节点派生类模板
CharTypech
结点内容
数据成员
WeightTypeweight
结点权值
MyLeafNode(constCharType&
ch,constWeightType&
w)
构造函数
virtual~MyLeafNode(){}
析构函数
CharTypeChar()htType>
返回叶子节点的字符
WeightTypeWeight()
boolIsLeaf()
MyHuffmanNode<
*Left()、MyHuffmanNode<
*Right()
返回结点的左右孩子
voidSetLeft(MyHuffmanNode<
*child)、voidSetRight(MyHuffmanNode<
*child)
设置结点的左右孩子
Huffman内部结点派生类模板
*lChild、MyHuffmanNode<
*rChild
结点的左右孩子
数据
MyNode(MyHuffmanNode<
*l,MyHuffmanNode<
*r,
constWeightType&
通过左右孩子以及权值构造Huffman树内部结点
virtual~MyNode(){}
Huffman树类模板
*root
根结点
String*charCodes
字符编码信息
*curCode
指向当前结点
intnum
叶子结点的个数
unsignedint(*CharIndex)(constCharType&
)
字符位置映射
voidCreatCode(MyHuffmanNode<
*r,charcode[],intlen=0)
生成字符编码
voidClear(MyHuffmanNode<
*r)
清空树
MyHuffmanTree(CharTypech[],WeightTypew[],intn,unsignedint(*ChIndex)(constCharType&
))
virtual~MyHuffmanTree(){}
StringEncode(CharTypech)
编码
LinkList<
CharType>
Decode(StringstrCode)
解码
Huffman压缩类
MyHuffmanTree<
char,unsignedlong>
*pMyHuffmanTree
Huffman树
ifstreaminfp、ofstreamoutfp
输入输出文件流
BufferTypebuf
字符缓存器
voidWrite(unsignedintbit)
向文件中写入信息
voidWriteToOutfp()
强制向文件写入信息
MyHuffmanCompress()
~MyHuffmanCompress(){}
voidCompress()
压缩
voidDecompress()
解压
说明:
在小顶堆的实现中要求各元素的大小,因为应重载关系运算符,然而重载运算符的操作数应包含非基本类型,不能全部是指针类型,为此定义一个辅助类结构模板如下:
template<
classCharType,classWeightType>
structMyHuffmanNodeHelp
{MyHuffmanNode<
*ptr;
4.源程序
系统中主要函数模板代码实现:
//生成字符编码
voidMyHuffmanTree<
:
CreatCode(MyHuffmanNode<
*r,charcode[],intlen)
{
if(r==NULL)return;
if(r->
IsLeaf())//如果是叶子节点,则存储编码
{
CharTypech=((MyLeafNode<
*)r)->
Char();
code[len]='
\0'
;
StringstrCode(code);
charCodes[(*CharIndex)(ch)]=strCode;
}
else//否则分别向左右两边搜索
code[len]='
0'
CreatCode(r->
Left(),code,len+1);
//向左分支搜索
1'
Right(),code,len+1);
//向右分支搜索
}
//构造Huffman树
CharIndex=ChIndex;
//字符位置映射
num=n;
charCodes=newString[num];
MinPriorityHeapQueue<
MyHuffmanNodeHelp<
>
minHeap;
//小顶堆
inti;
for(i=0;
i<
num;
i++)
MyHuffmanNodeHelp<
tmp;
tmp.ptr=newMyLeafNode<
(ch[i],w[i]);
//生成叶子结点
minHeap.InQueue(tmp);
//入栈
num-1;
t,t1,t2;
minHeap.OutQueue(t1);
//出栈
minHeap.OutQueue(t2);
//生成新的结点
t.ptr=newMyNode<
(t1.ptr,t2.ptr,t1.ptr->
Weight()+t2.ptr->
Weight());
minHeap.InQueue(t);
//新的结点入栈
MyHuffmanNodeHelp<
r;
minHeap.OutQueue(r);
root=r.ptr;
//根结点
curCode=root;
char*code=newchar[num];
CreatCode(root,code);
//生成编码
delete[]code;
//编码
StringMyHuffmanTree<
Encode(CharTypech)
returncharCodes[(unsignedint)(*CharIndex)(ch)];
//译码
MyHuffmanTree<
LinkList<
charList;
for(intpos=0;
pos<
strCode.Length();
pos++)
if(strCode[pos]=='
curCode=curCode->
Left();
//如果为0则向左分支搜索
else
Right();
//否则向右分支搜索
//如果到达叶子结点则说明译码完成,记录译码结果
if(curCode->
IsLeaf())
{
charList.Insert(charList.Length()+1,((MyLeafNode<
*)curCode)->
Char());
curCode=root;
}
returncharList;
//向目标文件写入一个比特
voidMyHuffmanCompress:
Write(unsignedintbit)
buf.bits++;
//缓存比特数自增1
buf.ch=(buf.ch<
<
1)|bit;
//将比特加入到缓存字符中
if(buf.bits==8)
{//缓存区已满,写入目标文件
outfp.put(buf.ch);
//写入目标文件
buf.bits=0;
//初始化比特
buf.ch=0;
//初始化ch
//强行将字符缓存写入目标文件
WriteToOutfp()
unsignedintlen=buf.bits;
if(len>
0)
for(unsignedinti=0;
i<
8-len;
Write(0);
//压缩文件
Compress()
charinfName[256],outfName[256];
//文件名
L1:
cout<
"
\t\t>
>
请输入需要压缩的文件名:
cin>
infName;
infp.open(infName,ios:
out);
//打开目标文件
if(!
infp)//打开文件失败
cout<
打开文件失败!
endl;
gotoL1;
infp.get();
if(infp.eof())//如果文件为空则提示用户
文件为空!
L2:
请设置压缩后的文件名称:
outfName;
//压缩目标文件
outfp.open(outfName,ios:
in);
outfp)//打开文件失败
gotoL2;
正在处理,请稍后......"
constunsignedlongn=256;
//字符个数
charch[n];
//字符数组
unsignedlongw[n];
//字符权值
unsignedlongi,size=0;
chartmpCh;
for(i=0;
n;
ch[i]=(char)i;
//初始化字符值
w[i]=0;
//初始化权值
infp.seekg(0,ios:
beg);
//使文件指针指向文件开始处
tmpCh=infp.get();
//从文件中读取一个字符
while(!
infp.eof())
w[(unsignedint)((unsignedchar)tmpCh)]++;
//字符tmpCh的频度自加一
size++;
//文件大小加一
tmpCh=infp.get();
//读取下一个字符
infp.close();
//关闭文件
if(pMyHuffmanTree!
=NULL)
deletepMyHuffmanTree;
pMyHuffmanTree=newMyHuffmanTree<
(ch,w,n,CharIndex);
outfp.write((char*)&
size,sizeof(unsignedlong));
//向文件中写入源文件的大小
i++)//向文件中写入字符出现的频度
outfp.write((char*)(&
w[i]),sizeof(unsignedlong));
buf.bits=0;
buf.ch=0;
//使文件指向开始处
StringstrTmp=pMyHuffmanTree->
Encode(tmpCh);
//编码信息
for(i=0;
(unsignedint)strTmp.Length();
{//向文件中写入信息
if(strTmp[i]=='
Write(0);
else
Write
(1);
WriteToOutfp();
//强行写入目标文件
outfp.close();
压缩结束."
//解压文件
Decompress()
请输入压缩文件名:
//打开文件
打开压缩文件失败!
if(infp.eof())
压缩文件为空!
请设置解压后文件的名称:
outfp)
infp.read((char*)&
//读取目标文件大小
for(i=0;
infp.read((char*)&
w[i],siz
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Huffman 压缩 试验报告 汇总