Huffman树及编码的实现
2017-04-11 20:09
274 查看
Huffman树及编码的实现
定义
Huffman树又称最优树,是一类带权路径长度最短的树,而Huffman编码是基于Huffman树生成的一种前缀编码,保证了可变编码的平均编码最短。生成方法
首先,假设有n个权值,则整个Huffman树的结点有2n-1个,未填充的节点有n-1个从n个权值中挑选两个权值最小的结点构成一棵树的叶子节点,生成的树的根节点的权值为两个叶子节点的和,n++;
重复上述步骤,直到所节点都有权重。(即循环n-1次)
Huffman代码如下
#include <iostream> #include <string> using namespace std; struct HuffmanNode{ int weight; int parent,lchild,rchild; }; void createHuffmanTree(HuffmanNode *& node, int *w, int n); void selectNode(HuffmanNode *node, int & s1, int &s2, int n); int main(){ HuffmanNode *node; int w[] = { 5, 29, 7, 8, 14, 23, 3, 11 }; createHuffmanTree(node, w, 8); system("pause"); return 0; } void createHuffmanTree(HuffmanNode *& node, int *w, int n){ int i; int s1, s2;//两个权重最小的Node int s = 2 * n - 1;//节点总数 node = new HuffmanNode[s + 1];//获取相应的空间大小 memset(node, 0, (s + 1)*sizeof(HuffmanNode)); for (i = 1; i <= n; i++){ node[i].weight = *w++; } for (i = n + 1; i <= s; i++){ selectNode(node, s1, s2, i-1); node[i].weight = node[s1].weight + node[s2].weight; node[i].lchild = s1; node[i].rchild = s2; node[s1].parent = i; node[s2].parent = i; } //对huffmanTree 进行编码 int start, c, f; char **res = (char**)malloc((n + 1)*sizeof(char*)); char *cd = (char*)malloc(n*sizeof(char)); cd[n - 1] = '\0'; for (int i = 1; i <= n; i++){ start = n - 1;//code最长有n-1位 for (c = i, f = node[i].parent; f != 0; c = f, f = node[f].parent){ if (node[f].lchild == c) cd[--start] = '0'; else cd[--start] = '1'; } res[i] = (char*)malloc((n - start)*sizeof(char)); strcpy_s(res[i],n-start, &cd[start]); } for (int i = 1; i <= n; i++){ cout << res[i] << endl; } } void selectNode(HuffmanNode *node, int & s1, int &s2,int n){ s1 = 0; s2 = 0; int i; int min = INT_MAX; for (i = 1; i <= n; i++){ if (node[i].parent == 0){ min = node[i].weight; break; } } for (i = 1; i <= n; i++){ if (node[i].parent == 0 && node[i].weight <= min){ min = node[i].weight; s1 = i; } } min = INT_MAX; for (i = 1; i <= n; i++){ if (node[i].parent == 0 && node[i].weight < min){ if (i == s1) continue; min = node[i].weight; s2 = i; } } }
以上的测试用例
w={5,29,7,8,14,23,3,11}对应的结果表格如下
No | weight | parent | lchild | rchild |
---|---|---|---|---|
1 | 5 | 9 | 0 | 0 |
2 | 29 | 14 | 0 | 0 |
3 | 7 | 10 | 0 | 0 |
4 | 8 | 10 | 0 | 0 |
5 | 14 | 12 | 0 | 0 |
6 | 23 | 13 | 0 | 0 |
7 | 3 | 9 | 0 | 0 |
8 | 11 | 11 | 0 | 0 |
9 | 8 | 11 | 1 | 7 |
10 | 5 | 12 | 3 | 4 |
11 | 15 | 13 | 8 | 9 |
12 | 29 | 14 | 5 | 10 |
13 | 42 | 15 | 6 | 11 |
14 | 58 | 15 | 2 | 12 |
15 | 100 | 0 | 13 | 14 |
相关文章推荐
- Huffman树实现文件压缩编码
- Huffman树实现与应用(编码解码压缩解压缩)
- C++Huffman树的构造实现及编码译码过程
- Huffman树编码-优先队列实现
- Huffman树与编码的简单实现
- huffman树的生成与编码的实现
- Huffman树及其编码实现
- 利用Huffman树进行文本编码解码的实现
- php中循环实现(字符串,对象,或者数组)编码相互转换
- LZW编码的学习与实现
- 哈夫曼树的构造以及编码实现
- PHP mb_convert_encoding 获取字符串编码类型实现代码
- 利用ADO STREAM实现BASE64编码和解码
- 地理反编码的实现
- C++实现RTMP协议发送H.264编码及AAC编码的音视频
- 24进制 编码实现
- 编码实现读取文本的方法
- iconv C++ 实现 字符 (语言) 编码 转换
- Javascript base64编码实现代码
- Spring(八)编码剖析@Resource注解的实现原理