【哈夫曼编码模板】
来源:互联网 发布:nba历年总决赛数据 编辑:程序博客网 时间:2024/05/17 07:48
哈夫曼树又称最优二叉树,是一种带权路径长度最短的二叉树。所谓树的带权路径长度,就是树中所有的叶结点的权值乘上其到根结点的路径长度(若根结点为0层,叶结点到根结点的路径长度为叶结点的层数)。树的带权路径长度记为WPL=(W1*L1+W2*L2+W3*L3+...+Wn*Ln),N个权值Wi(i=1,2,...n)构成一棵有N个叶结点的二叉树,相应的叶结点的路径长度为Li(i=1,2,...n)。可以证明哈夫曼树的WPL是最小的。
/*示例 ****哈夫曼编码****请输入结点个数:8输入这8个元素的权值(均为整形):1:272:43:874:215:26:217:18:25*/#include <stdio.h>#include <stdlib.h>#include <string.h>typedef struct{ unsigned int weight; //用来存储各个结点的权值 unsigned int parent,LChild,RChild; //指向双亲、孩子结点的指针 } HTNode, *HuffmanTree; //动态分配数组,存储哈夫曼树 typedef char *HuffmanCode; //动态分配数组,存储哈夫曼树///选择两个parent为0,且weight最小的结点s1和s2 void Select(HuffmanTree *ht,int n,int *s1,int *s2){ int i,min; for(i=1; i<=n; i++) { if((*ht)[i].parent==0) { min=i; break; } } for(i=1; i<=n; i++) { if((*ht)[i].parent==0){ if((*ht)[i].weight<(*ht)[min].weight) min=i;} } *s1=min; for(i=1; i<=n; i++) { if((*ht)[i].parent==0 && i!=(*s1)){ min=i; break;} } for(i=1; i<=n; i++) { if((*ht)[i].parent==0 && i!=(*s1)){ if((*ht)[i].weight<(*ht)[min].weight) min=i;} } *s2=min;}///构造哈夫曼树ht,w存放已知n个权值 void CrtHuffmanTree(HuffmanTree *ht,int *w,int n){ int m,i,s1,s2; m=2*n-1; //总共的结点数 *ht=(HuffmanTree)malloc((m+1)*sizeof(HTNode)); for(i=1; i<=n; i++) //1-n号存放叶子结点,初始化 { (*ht)[i].weight=w[i]; (*ht)[i].LChild=0; (*ht)[i].parent=0; (*ht)[i].RChild=0; } for(i=n+1; i<=m; i++) //非叶子结点的初始化 { (*ht)[i].weight=0; (*ht)[i].LChild=0; (*ht)[i].parent=0; (*ht)[i].RChild=0; } printf("\n?哈夫曼树为: \n"); for(i=n+1; i<=m; i++) //创建非叶子结点,建哈夫曼树 { /*在(*ht)[1]~(*ht)[i-1]的范围内选择两个parent为0且weight最小的结点,其序号分别赋值给s1、s2*/ Select(ht,i-1,&s1,&s2); (*ht)[s1].parent=i; (*ht)[s2].parent=i; (*ht)[i].LChild=s1; (*ht)[i].RChild=s2; (*ht)[i].weight=(*ht)[s1].weight+(*ht)[s2].weight; printf("%d (%d, %d)\n",(*ht)[i].weight,(*ht)[s1].weight,(*ht)[s2].weight); } printf("\n");} //从叶子结点到根,逆向求每个叶子结点对应的哈夫曼编码void CrtHuffmanCode(HuffmanTree *ht, HuffmanCode *hc, int n){ char *cd; //定义的存放编码的空间 int a[100]; int i,start,p,w=0; unsigned int c; hc=(HuffmanCode *)malloc((n+1)*sizeof(char *)); //分配n个编码的头指针 cd=(char *)malloc(n*sizeof(char)); //分配求当前编码的工作空间 cd[n-1]='\0'; //从右向左逐位存放编码,首先存放编码结束符 for(i=1; i<=n; i++) //求n个叶子结点对应的哈夫曼编码 { a[i]=0; start=n-1; //起始指针位置在最右边 for(c=i,p=(*ht)[i].parent; p!=0; c=p,p=(*ht)[p].parent) //从叶子到根结点求编码 { if( (*ht)[p].LChild==c){cd[--start]='1'; //左分支标1a[i]++;} else {cd[--start]='0'; //右分支标0a[i]++;} } hc[i]=(char *)malloc((n-start)*sizeof(char)); //为第i个编码分配空间 strcpy(hc[i],&cd[start]); //将cd复制编码到hc } free(cd); for(i=1; i<=n; i++) printf(" 权值为%d的哈夫曼编码为:%s\n",(*ht)[i].weight,hc[i]); for(i=1; i<=n; i++) w+=(*ht)[i].weight*a[i]; printf(" 带权路径为:%d\n",w);}int main(){ HuffmanTree HT; HuffmanCode HC; int *w,i,n,wei; printf("**哈夫曼编码**\n" ); printf("请输入结点个数:" ); scanf("%d",&n); w=(int *)malloc((n+1)*sizeof(int)); printf("\n输入这%d个元素的权值:\n",n); for(i=1; i<=n; i++) { printf("%d: ",i); fflush(stdin); scanf("%d",&wei); w[i]=wei; } CrtHuffmanTree(&HT,w,n); CrtHuffmanCode(&HT,&HC,n); system("pause"); return 0;}
阅读全文
0 0
- 【哈夫曼编码模板】
- sql编码规范模板
- 用模板写哈夫曼编码
- 个人编码模板
- 个人编码模板
- 哈夫曼树与哈夫曼编码详解及C++模板实现
- 哈夫曼编码,应用模板特化递归+bind函数绑定
- Freemarker模板文件编码问题
- Velocity编码式渲染模板
- 模板编码方法(template method)
- 模板实现所有API硬编码导出
- Destoon B2B模板编码转换工具
- Django读取模板时报编码错误
- eclipse 安装freemarker 模板增加编码颜色
- 代码模板和编码的设置
- django 模板包含中文编码报错
- JDBC编码的代码模板(最终版)
- Pycharm自定义Python模板文件编码
- 自动导引运输车AGV与AGC对比
- 排序算法C++&&Python实现---归并排序
- 学生信息管理系统—知识篇
- java程序员的大数据之路(2):创建第一个Hadoop程序
- python里面几个小函数的用法(map, zip, round)
- 【哈夫曼编码模板】
- 母子基金拆分合规则
- StringBuffer的用法
- tomcat配置server.xml
- php 微信二次分享 图片出现不了、描述变域名等问题
- Android Camera相机原理解析(源码)
- Linux登陆——账号和密码文件 /etc/passwd和/etc/shadow
- 《深入理解java虚拟机》学习笔记9——对象的创建
- svc_recv函数实现详解