哈弗曼编码
来源:互联网 发布:mac 打开系统文件夹 编辑:程序博客网 时间:2024/06/05 02:34
#include "iostream"#include "queue"#include "vector"#include "string"using namespace std;struct huffmanTree{ char data; //表示的字符 int weight; //字符出现的频率,权值 int parent; //父亲的下标 int lchild; //左孩子下标 int rchild; //右孩子下标 int index; //自己的下标 int dir; //本树的标识,dir=0为父亲的左孩子,dir=1为父亲的右孩子,dir=-1都不是 int size; //本字符编码所需的位数; string code; //本字符的编码值,为一串二进制字符 huffmanTree() { weight = parent = lchild = rchild = dir = -1; data = ' '; size = 0; code = ""; } bool operator < (const huffmanTree &t) const { return weight > t.weight; }};vector<huffmanTree> h; //相当于一个并查集,存储所有的父子关系priority_queue<huffmanTree> pq; //存储数的优先队列,字符出现频率小的树先出队列int size = 0; // 待编码字符数目//初始化,将每一个字符作为一棵树//n为字符个数,c[]为字符,w[]为字符出现频率void init(int n, char c[], int w[]){ int i; for(i=0; i<n; i++) { huffmanTree ht; //树中只有一个节点 ht.parent = ht.lchild = ht.rchild = ht.dir = -1; ht.data = c[i]; ht.weight = w[i]; ht.index = size++; h.push_back(ht); pq.push(ht); //单节点树入队列 }}//进行编码void encode(){ huffmanTree ht1, ht2, ht; while(pq.size()>=2) //一直合并下去,当优先队列中只剩下一棵树时结束 { ht1 = pq.top(); pq.pop(); //选择权值最小的两个根 ht2 = pq.top(); pq.pop(); ht.weight = ht1.weight + ht2.weight; //将它们作为左右子树构造新树 ht.index = h[ht1.index].parent = h[ht2.index].parent = h.size(); //建立父子关系 ht.lchild = ht1.index; //较小的为左子树 ht.rchild = ht2.index; //较大的为右子树 ht.dir = -1; //当前树为树根 h[ht1.index].dir = 0; //左子树编码为0 h[ht2.index].dir = 1; //右子树编码为1 h.push_back(ht); if(pq.empty()) break; pq.push(ht); } int i; for(i=0; i<size; i++) { int index = i; string s = ""; while(h[index].parent != -1) //自底向上搜索并查集 { s = (h[index].dir?"1":"0") + s; //因为是自底向上,所以要倒过来 h[i].size++; //编码所占位数增加 index = h[index].parent; } h[i].code = s; //得到字符的二进制编码 }}void print(int n) //打印字符编码、编码所占总空间{ int i; int sum = 0; for(i=0; i<n; i++) { cout << h[i].data << "(" << h[i].weight << " k): " << h[i].code << endl; sum += (h[i].size * h[i].weight); } printf("文件需要总的存储位数为:%d kbits\n", sum);}int main(){ int n = 6; char c[] = {'a', 'b', 'c', 'd', 'e', 'f'}; int w[] = {45, 13, 12, 16, 9, 5 }; init(n, c, w); encode(); print(n); return 0;}
0 0
- 香农编码、费诺编码、哈弗曼编码
- 哈弗曼编码
- 哈弗曼编码
- 哈弗曼编码
- 哈弗曼编码
- 哈弗曼编码
- 哈弗曼编码
- 哈弗曼编码
- 哈弗曼编码
- 哈弗曼编码
- 哈弗曼编码
- 哈弗曼编码
- 哈弗曼编码
- 哈弗曼编码
- 哈弗曼编码
- 哈弗曼编码
- 哈弗曼编码
- 哈弗曼编码(C++)
- ios之TableViewCell重用机制避免重复显示问题
- 静态数码管显示0-F
- postgresql异步流复制Hot Standby
- 基于jquery的循环左右滚动和上下滚动效果
- Matlab调用C/C++之设置过程
- 哈弗曼编码
- Delphi 关于DLL中使用TThread类或其子类的使用注意事项
- xamarin
- GridViewActivity gridview显示时的动画
- 远程桌面无法使用剪切板的有效解决方法
- JAVA分组以及JAVA分页
- Java性能优化
- Hadoop Hive sql语法详解
- UART 基础知识