哈夫曼编码算法及其实现
来源:互联网 发布:淘宝泳衣模特是谁 编辑:程序博客网 时间:2024/05/18 02:34
概念
哈夫曼编码就是利用哈夫曼树构造的最优编码。
算法
基本思想是:为出现次数较多的字符编以较短的编码。
对于每个字符,根据其出现的次数为权值,构造哈夫曼树。然后从根到每个叶子节点的路径上,左分支赋值0,右分支赋值1,个分支构成一个二进制串,这个二进制串就是哈夫曼编码。
C++代码
#include <iostream>#include <cstring>#include <algorithm>using namespace std;//哈夫曼树的存储表示typedef struct{ int weight; // 权值 int parent, lChild, rChild; // 双亲及左右孩子的下标 }HTNode, *HuffmanTree;// 哈夫曼编码表的存储表示typedef struct{ char** code; // 编码表 int n; // 编码数 }HuffmanCode;// 选择权值最小的两颗树 void SelectMin(HuffmanTree hT, int n, int &s1, int &s2){ s1 = s2 = 0; int i; for(i = 1; i < n; ++ i){ if(0 == hT[i].parent){ if(0 == s1){ s1 = i; } else{ s2 = i; break; } } } if(hT[s1].weight > hT[s2].weight){ int t = s1; s1 = s2; s2 = t; } for(i += 1; i < n; ++ i){ if(0 == hT[i].parent){ if(hT[i].weight < hT[s1].weight){ s2 = s1; s1 = i; }else if(hT[i].weight < hT[s2].weight){ s2 = i; } } }}// 构造有n个权值(叶子节点)的哈夫曼树 void CreateHufmanTree(HuffmanTree &hT){ int n, m; cin >> n; m = 2*n - 1; hT = new HTNode[m + 1]; // 0号节点不使用 for(int i = 1; i <= m; ++ i){ hT[i].parent = hT[i].lChild = hT[i].rChild = 0; } for(int i = 1; i <= n; ++ i){ cin >> hT[i].weight; // 输入权值 } hT[0].weight = m; // 用0号节点保存节点数量 /****** 初始化完毕, 创建哈夫曼树 ******/ for(int i = n + 1; i <= m; ++ i){ int s1, s2; SelectMin(hT, i, s1, s2); hT[s1].parent = hT[s2].parent = i; hT[i].lChild = s1; hT[i].rChild = s2; // 作为新节点的孩子 hT[i].weight = hT[s1].weight + hT[s2].weight; // 新节点为左右孩子节点权值之和 }}// 构造根据哈夫曼树来哈夫曼编码 void CreateHuffmanCode(HuffmanTree hT, HuffmanCode &hC){ hC.n = (hT[0].weight + 1)/2; hC.code = new char*[hC.n + 1]; // 0位置不使用 char *cd = new char[hC.n]; // 临时存放每个编码 for(int i = 1; i <= hC.n; ++ i){ // 每次从叶子节点向上回溯构造编码 int len = 0, child = i, parent = hT[i].parent; while(parent != 0){ if(hT[parent].lChild == child){ cd[len ++] = '0'; } else{ cd[len ++] = '1'; } child = parent; parent = hT[parent].parent; } cd[len] = 0; reverse(cd, cd + len); // 将序列翻转 hC.code[i] = new char[len]; strcpy(hC.code[i], cd); } delete[] cd;}// 输出哈夫曼表 void PrintHuffmanCode(HuffmanCode &hC){ for(int i = 1; i <= hC.n; ++ i){ cout << hC.code[i] << endl; }}// 销毁哈夫曼树 void DestoryHuffmanTree(HuffmanTree &hT){ delete[] hT; hT = NULL;}// 销毁哈夫曼编码表void DestoryHuffmanCode(HuffmanCode &hC){ for(int i = 1; i <= hC.n; ++ i){ delete[] hC.code[i]; } delete[] hC.code; hC.code = NULL;}int main(){ HuffmanTree hT; CreateHufmanTree(hT); HuffmanCode hC; CreateHuffmanCode(hT, hC); PrintHuffmanCode(hC); DestoryHuffmanTree(hT); DestoryHuffmanCode(hC); return 0;}
运行结果
对于串“abcdabcdaaaaabbbdd
”,
a、b、c、d出现的次数分别为7、5、2、4,构造的编码表为:
ps:更完整的解码编码可以参考:http://www.cnblogs.com/Jezze/archive/2011/12/23/2299884.html
0 0
- 哈夫曼编码算法及其实现
- 哈夫曼编码算法实现
- Huffman树及其编码实现
- KMP算法及其实现
- KNN算法及其实现
- lasso算法及其实现
- kmeans算法及其实现
- 哈夫曼树及其算法实现
- lasso算法及其实现
- KNN算法及其实现
- 遗传算法及其实现
- 蒙特卡洛算法及其实现
- lasso算法及其实现
- 优先队列的实现及其在哈夫曼编码中的应用
- 哈夫曼树建立、哈夫曼编码算法的实现
- 基本的哈夫曼编码算法的实现
- 算法学习-哈夫曼编码(c++实现)
- 贪心算法--哈夫曼编码(java实现 )
- 基础对发展高度的重要性
- 16位汇编写的五子
- 《算法学习与数据结构》part1 算法分析与数据结构之表、栈和队列
- hdu1540 Tunnel Warfare--单点更新查询 & 区间合并
- input type=file accept中可以限制的文件类型
- 哈夫曼编码算法及其实现
- org.codehaus.jackson.map.JsonMappingException: Can not deserialize instance of java.util.ArrayList o
- 每个程序员1小时内必须解决的5个编程问题
- 想要裸辞不掉价,一定要这么做!
- Go语言编程(三)之过过瘾
- 引领新未来SOA服务框架,未来发展的方向
- POJ 2387 Bellman双重边
- win10系统免费激活
- 模型基图像编码