利用哈夫曼编码实现压缩和解压缩
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
利用哈夫曼编码实现压缩和解压缩
1.问题描述
利用哈夫曼编码.实现压缩和解压缩的数据元素具有如下形式:
结点:
weight:存储结点的权值
parent:是结点双亲在向量中的下标
lchild:结点的左儿子向量下标
rchild:结点右儿子向量下标
bits:位串.存放编码
ch:字符
start:编码在位串中的起始位置
文件操作记录:
b:记录字符在数组中的位置
count:字符出现频率(权值)
lch、rch、parent:定义哈夫曼树指针变量
bits[256]:定义存储哈夫曼编码的数组
2.功能需求
对于给定的一组字符.可以根据其权值进行哈夫曼编码.并能输出对应的哈夫曼树和哈夫曼编码;实现哈夫曼解码。能够分析文件.统计文件中出现的字符.再对文件进行编码.实现文件的压缩和解压缩.能够对于文件的压缩.
比例进行统计.能够打印文件。
3.实现要点
(1)构造哈弗曼树过程中.首先将初始森林的各根结点的双亲和左、右儿子指针置-1;叶子在向量T的前n个分量中.构成初始森林的n个结点;对森林中的树进行n次合并.并产生n-1个新结点.依次放入向量T的第i个分量中。
(2)编码过程中.从叶子T[i]出发.利用双亲的指针找到双亲T[p];再根据T[p]的孩
子指针可以知道T[i]是T[p]的左儿子还是右儿子.若是左儿子.则生成代码0.否则生成代码1;
(3)在文件压缩和解压过程中.主要参考网上资料.每个步骤都基本理解.并注上了详细解析。
4.函数定义
功能:输入权重.构造一棵哈弗曼树
void huffman(hftree T)
{
if(n<1 || n > m)return;
int i,j,p1,p2;
float small1,small2;
//初始化
cout<<"请输入叶子权重(5个):"< for(i=0; i { T[i].parent = -1; T[i].lchild = T[i].rchild = -1; } //输入叶子权值 for(i=0; i { cin>>T[i].weight; } for(i=n; i { p1 = p2 = -1; small1 = small2 = MAX_FLOAT; for(j=0; j<=i-1; j++) { if(T[j].parent != -1)continue; if(T[j].weight < small1) { small2 = small1; small1 = T[j].weight; p2 = p1; p1 = j; } else if(T[j].weight < small2) { small2 = T[j].weight; p2 = j; } } T[p1].parent = T[p2].parent = i; T[i].parent=-1; T[i].lchild=p1; T[i].rchild=p2; T[i].weight=small1 + small2; } cout<<"创建成功!"< } 功能:对哈弗曼树进行编码 void encode(codelist codes, hftree T) { int i,c,p,start; cout<<"请输入需要编码的字符(5个):"< for(i=0; i { cin>>codes[i].ch; start=n; c=i; p=T[i].parent; while(p!=-1) { start--; if(T[p].lchild==c) codes[i].bits[start]='0'; else codes[i].bits[start]='1'; c=p; p=T[p].parent; } codes[i].start=start; } cout<<"输入成功!:"< cout<<"编码表:"< for(int x=0; x { cout< for(int q=codes[x].start;q cout< } } 函数功能:对哈弗曼树进行解码 void decode(codelist codes,hftree T) { int i,c,p,b; int endflag; endflag=-1; i=m-1; while(cin>>b,b!=endflag) { if(b==0) i=T[i].lchild; else i=T[i].rchild; if(T[i].lchild==-1) { cout< i=m-1; } } if(i!=m-1)cout<<"编码有错!\n"; } 功能:对文件进行压缩.统计压缩率 void compress() {