- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
-数据结构-树
第六章 树
第六节 哈夫曼树及其应用
应用实例:文件压缩、解压。
一、术语
路径 :连接结点之间的若干分支。
路径长度:路径的分支数。
结点路径长度:从根到该结点的路径长度。
树的路径长度:树中所有叶子结点的路径长度之和。
结点带权路径长度:结点路径长度与结点权的积。
树的带权路径长度:树中所有叶子结点的带权路径长度之和。
哈夫曼树(最优二叉树):
在叶子结点确定的前提下,带权路径长度最小的二叉树。
WPL=46 WPL=36 WPL=35 经验:
①没有度为1的结点。
②权值越大的叶子离根越近,树的带权路径长度越小。
二、构造哈夫曼树的算法
已知:N个结点的权值为W1,……,WN,构造算法如下:
①根据(W1,……,WN)构成森林F=(T1,……,TN),每棵二叉树Ti有且只有一个根结点,权为Wi,左右子树为空;
②在F中选取二棵根的权值最小的树Ti、Tj,权为Wi、Wj,作为左右子树合成一棵新树Tk,Tk的根的权Wk=Wi+Wj;
③在F中删除Ti、Tj,加入Tk;
④重复②③,循环N-1次,F中只剩一棵树,即为哈夫曼树。
示例:0.4, 0.2, 0.1, 0.5
示例:0.22, 0.3, 0.4, 0.28
三、哈夫曼编码
1、信息编码的目标
源文件 =》 目标文件
编码目标: 目标文件长度尽可能短。
2、编码方法
定长编码 A B C D 00 01 10 11 不定长编码
(统计编码) A B C D 0 10 110 111 统计编码原理:①基于概率分布特性;②编码长度不固定。
频率高的符号用较少的位。
问题1:
A的编码可以为1吗?B的编码可以为11吗?
前缀编码:任何符号的编码都不是另一符号编码的前缀。
统计编码必须是前缀编码!
问题2:编码的效率?
设 S1, S2, … , Sn是被编码的一组符号,
P1, P2, … , Pn是各自出现的概率,
L1, L2, … , Ln是码长,
则平均码长:
3、哈夫曼树中的哈夫曼编码
哈夫曼树的意义:
叶子:待编码的符号;
权值:待编码的符号的出现频率
叶子的路径:符号的哈夫曼编码
记:左分支=0,右分支=1。
哈夫曼编码的性质:
①前缀编码:各个叶子的路径决不会相互包含。
②高效编码:树的带权路径长度=平均码长
4、压缩/解压软件的思路
设压缩单位为字节,
压缩模块的设计思路:
①统计源文件:0,1,……,255的出现次数=》“频率表”;
②根据“频率表”构造哈夫曼树;
③读取各字符的哈夫曼编码;
④将“频率表”写入压缩文件头;(文件头的格式设计?)
⑤翻译源文件,写入压缩文件。
解压模块的设计思路:
①读压缩文件头,得到“频率表”;
②根据“频率表”重构哈夫曼树;
③读压缩文件中的0/1串,从根搜索至叶子,将叶子对应的字符写入“解压文件”;
④重复③,直至译完压缩文件。
四、哈夫曼算法:建树、计算编码
存储结构:顺序?链式?
若结点数确定:采用静态链表。
若结点数不定:采用动态链表。
#define N 4 /* 需编码的字符数 */
#define M 7 /* 哈夫曼树的结点数=2N-1 */
typedef struct //每个字符及相应权值
{ char ch;
float weight;
}Char_Weight;
typedef struct
{ char ch;
float weight;
int parent,lchild,rchild; //父结点,左、右孩子
}HuffNode;
typedef struct //每个字符的编码结构
{ int start;
int bits[N];
}HuffCode;
main()
{ Char_Weight W[N];
HuffNode HT[M]; HuffCode HC[N];
ReadWeight(W); // 读入权值
Huffman_Create(HT,W); //建树HT[M]
Huffman_Coding(HT,HC); //读编码HC[N]
}
void Huffman_Create(HuffNode HT[],Char_Weight W[])
{ for(i=0;iN;i++) // 初始化N个树的森林
{ HT[i].ch= W[i].ch; // 为将来译码作准备
HT[i].parent=HT[i].lc
文档评论(0)