哈夫曼编码
来源:互联网 发布:淘宝客服视频教程 编辑:程序博客网 时间:2024/06/05 02:12
今天中秋节,同学都回家了,自己离家太远待在宿舍无聊就看看哈夫曼代码,顺手写了写,特此博客一篇,望多多指教:
对一组数进行哈夫曼树的构建:
假设有n个权值,则构造出的哈夫曼树有n个叶子结点。 n个权值分别设为 w1、w2、…、wn,则哈夫曼树的构造规则为:
(1) 将w1、w2、…,wn看成是有n 棵树的森林(每棵树仅有一个结点);
(2) 在森林中选出两个根结点的权值最小的树合并,作为一棵新树的左、右子树,且新树的根结点权值为其左、右子树根结点权值之和;
(3)从森林中删除选取的两棵树,并将新树加入森林;
(4)重复(2)、(3)步,直到森林中只剩一棵树为止,该树即为所求得的哈夫曼树。[2]
代码如下:
void select(HuffmanTree ht,int n,int *s1,int *s2){ int min1 = INF; int min2 = INF; int i; *s2 = 0; *s1 = 0; for(i = 1; i <= n; i++) { if(ht[i].weight <= min1 && ht[i].parent == 0)//为了下一个次查找排除查找过得节点 { min1 = ht[i].weight; *s1 = i; } } for(i = 1; i <= n; i++) { if(ht[i].weight <= min2 && ht[i].parent == 0 && i != *s1) { min2 = ht[i].weight; *s2 = i; } }}void InitHuffman(HuffmanTree ht,int w[],int n){ int i; int m; //1-n号单元存放叶子节点,初始化 for( i = 1; i <= n; i++) { ht[i].weight = w[i-1]; ht[i].parent = 0; ht[i].LChild = 0; ht[i].RChild = 0; } //n+1—m号单元存放非叶子节点,初始化 m = 2*n - 1; for(i = n+1; i <= m; i++) { ht[i].weight = 0; ht[i].parent = 0; ht[i].LChild = 0; ht[i].RChild = 0; }}void CrtHuffmanTree(HuffmanTree ht,int w[],int n){ int s1,s2; InitHUffman(ht,w,n); for(i = n+1; i<= m; i++) {//创建哈夫曼树 select(ht,i-1,&s1,&s2);//从0至(i-1)行中选最小的两个值 ht[i].weight = ht[s1].weight + ht[s2].weight; ht[s1].parent = i; ht[s2].parent = i; ht[i].LChild = s1; ht[i].RChild = s2; }}
这时候二叉树就构建成功了,如果想进行编码,则直接遍历每一个叶子节点就OK
得到编码
void CrtHuffmanCode(HuffmanTree ht,HuffmanCode hc,int n){ char *cd; int i; int c; int start; int p; cd = (char*)malloc((n+1)*sizeof(char));//分配当前编码的工作空间 cd[n-1] = '\0';//从右向左逐位存放编码,首先存放编码结束符 for(i = 1; i <= n; i++) { start = n-1;//cd中的位置 c = i;//第几个点 p = ht[i].parent; while(p != 0) { --start; if(ht[p].LChild == c) {//左分支标0 cd[start] = '0'; } else {//右分支标1 cd[start] = '1'; } c = p; p = ht[p].parent; } //为第i个编码分配空间 hc[i] = (char*)malloc((n-start)*sizeof(char)); strcpy(hc[i],&cd[start]);//把编码复制到hc[i]里面 }}
同时祝自己中秋节快乐
阅读全文
0 0
- 信源编码---哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 线性布局(LinearLayout)
- mysql中用户的创建及权限相关的说明
- golang map的遍历
- Android Studio Run 'app'安装APK到设备的过程
- Android移动开发-使用多线程进行网络聊天室通信的实现
- 哈夫曼编码
- 架构师日记——ActiveMQ使用场景和优化建议
- LeetCode[307]Range Sum Query
- 我忽然发现我写的cve漏洞管理系统简直就是redmine的一个小模块
- Android LocalBroadcastManager 的使用总结
- 电话拨号示例
- Elastic-job源码学习——环境准备
- ubuntu 如何通过ssh 登陆远程VPS
- HelloAndroid