数据结构学习——Huffman树及其应用
来源:互联网 发布:飞狐淘宝客cms 编辑:程序博客网 时间:2024/04/29 08:12
Huffman树又叫最优树,是一类带权路径长度最短的树,有着广泛的应用。
1、 最优二叉树
从树中一个节点到另一个结点之间的分支构成这两个结点之间的路径,路径上的分支数目称做路径长度。树的路径长度是从树根到每一个结点的路径长度之和。结点的带权路径长度为从该节点到树根之间的路径长度与节点上权的乘积,树的带权路径长度为树中所有叶子节点的带权路径长度之和,记作 。
假设有n个权值 ,试构造一棵有n个叶子节点的二叉树,每个叶子节点的带权为 ,则其中带权路径长度WPL最小的二叉树称作最优二叉树或Huffman树。
例如,图1中3棵二叉树有4个叶子节点a、b、c、d,分别带权7、5、2、4,则他们带权路径长度分别为
其中(c)树最小。恰为Huffman树。
图1 具有不同带权路径长度的二叉树
那么,如何构造Huffman树呢?步骤如下:
(1) 将给定的n个权值 构成一个二叉树集合,每个二叉树根节点分别带权 ,左右子树为空。
(2) 选择两个最小权值的二叉树分别作为左右子树构造一棵新的二叉树,新树的根节点权值为左右子树之和。
(3) 在二叉树集合中删除合并的两棵二叉树,添加新得到的二叉树。
(4) 重复步骤(2)(3)直到集合中只含一棵二叉树为止。
如图2所示,为Huffman树的构造过程。
图2 Huffman树的构造过程
2、 Huffman编码
利用二叉树来设计二进制的前缀编码(任一字符编码都不是另一个字符编码的前缀),假设每种字符在电文中出现的次数为 ,其编码长度为 ,若电文有n中字符,则编码总长度为 ,由前面得知,为使编码总长度最短,应以n中字符出现的频率为权重设计一棵Huffman树,由该树得到的编码即为Huffman编码。
Huffman编码具体做法:由于Huffman树中没有度为1的结点,则一棵有n个叶子节点的Huffman树共有2n-1个结点,可以存储在一个2n-1的数组中。由于构成Huffman树后,为求编码需从叶子节点出发到根,而为译码需从根出发的叶子节点,则对每个结点而言,既需知道双亲信息,又需知道孩子结点的信息。
Huffman编码的C程序:
typedef struct{ unsigned int weight; unsigned int parent,lchild,rchild;}HNode,*huffmanTree;//动态分配数组存储Huffman树typedef char* HuffmanCode;//动态分配数组存储Huffman编码表//Huffman编码void HuffmanCoding(huffmanTree HT,HuffmanCode HC,int * w,int n){ //w存放n个字符的权值,构造Huffman数HT,并求出n个字符的Huffman编码HC if (n<=1) { return; } int m=2*n-1; HT=(huffmanTree)malloc((m+1)*sizeof(HNode)); for(int i=1;i<=n;i++) { HT[i].lchild=0;HT->rchild=0; HT->parent=0;HT->weight=w[i]; } for(;i<=m;i++) { HT[i].lchild=0;HT->rchild=0; HT->parent=0;HT->weight=0; } //构建Huffman树 int min1,min2; for(i=n+1;i<=m;i++) { SelectMinWeight(w,i-1,min1,min2);//在H[1...i-1]选择parent为0且weight最小的的结点,其序号分别为min1,min2 HT[min1].parent=i;HT[min2].parent=i; HT[i].lchild=min1;HT[i].rchild=min2; HT[i].weight=HT[min1].weight+HT[min2].weight; } //从叶子到根逆向求每个字符的Huffman编码 HC=(HuffmanCode)malloc((n+1)*sizeof(char*));//分配n个字符编码的头指针向量 char* cd=(char*)malloc(n*sizeof(char));//分配求编码的工作空间 cd[n-1]='\0'; for(int i=1;i<=n;i++)//逐个字符求Huffman编码 { int start=n-1; for (int c=i,int f=HT[i].parent;f!=0;c=f,f=HT[f].parent)//从叶子到根逆向求编码 { if (HT[f].lchild==c) { cd[--start]='0'; } else cd[--start]='1'; } HC[i]=(char*)malloc((n-start)*sizeof(char));//为第i个字符编码分配空间 strcpy(HC[i],cd[start]); } free(cd);}
参考文献:严蔚敏《数据结构》
- 数据结构学习——Huffman树及其应用
- [数据结构与算法]Huffman树及其应用
- Huffman树及其应用
- huffman树及其应用
- 数据结构和算法——Huffman树和Huffman编码
- 数据结构学习笔记--Huffman树
- 常用数据结构之Huffman树及应用
- Huffman树的应用 (数据结构)
- 数据结构学习笔记——栈及其应用
- 数据结构 — 浅析huffman树原理及实现
- 常用数据结构——队列及其应用
- 常用数据结构——栈及其应用
- 数据结构 树 Huffman编码
- Huffman树及Huffman编码(数据结构)
- huffman树的应用——文件压缩
- 数据结构与算法学习笔记——堆栈及其应用(10以内简单四则计算器)
- 【学习笔记----数据结构13-哈夫曼树及其应用】
- Huffman树及其编码实现
- Item 2:避免使用define Effective C++笔记
- Android实现浮层的上下滑动(支持内部添加View)
- UI架构设计的演化
- Item 3:尽量使用常量 Effective C++笔记
- ural 1136. Parliament 中后序建树
- 数据结构学习——Huffman树及其应用
- 资源网站
- linux chmod命令
- 完美解决程序启动,Activity之间切换,黑屏问题
- TRACE
- error C2668: “pow”: 对重载函数的调用不明确
- Android5.1FM模块学习----向前台发送消息
- Json工具,JsonObject、JsonArray、List<Map<String, Object>>、Map<String, Object>互转。
- JavaMail发送邮件找回密码的功能