哈夫曼树以及哈夫曼编码的创建
2016-01-19 10:21
309 查看
#include<stdio.h> #include<string.h> #define Maxvalue 20 #define Maxleaf 15 #define Maxnode (2*Maxleaf-1) int n=0,len,j,m; typedef struct { int num; //存放字母的种类 char ch; //存放字母的个数 }inf; inf info[Maxleaf]; //定义此类型数组 typedef struct { int weight; //权值 int parent; //双亲 int lchild; //左孩子 int rchild; //右孩子 }HTnode; HTnode Hofftree[Maxnode]; //定义此类型数组 typedef struct { char cd[10]; //存储每个结点的哈夫曼编码 int start; //起始位置 }Hcode; Hcode hcd[Maxleaf]; //定义此类型数组 void Count() //统计字符串中字母总个数以及各个字母的个数 { int k,i; char s[Maxvalue]; printf("请输入字符串:\n"); scanf("%s",&s); len=strlen(s); printf("字符串字母的个数为:%d\n",len); info[0].ch=s[0]; info[0].num=1; for(k=1;k<=len;k++) { for(m=0;m<=n;m++) //s[k]与s[m]是同一个字母num加1 if(info[m].ch==s[k]) { ++info[m].num; break; } if(m>n) //有新的字母s[k]出现 { info[++n].ch=s[k]; info .num=1; } } for(j=0;j<n;j++) { printf("字符%c的个数为:%d\n",info[j].ch,info[j].num); } for(i=0;i<n;i++) //将字母的权值赋予节点 Hofftree[i].weight=info[i].num; } void CreatHT(HTnode Hofftree[]) //构造哈夫曼树 { int i,p,lnode,rnode,k; double min1,min2; for(i=0;i<=2*n-1;i++) //所有结点相关域置初值-1 Hofftree[i].parent=Hofftree[i].lchild=Hofftree[i].rchild=-1; for(i=n;i<2*n-1;i++) //构造哈夫曼树 { min1=min2=32767; lnode=rnode=-1; //lnode和rnode为最小权值的两个结点的位置 for(k=0;k<=i-1;k++) if(Hofftree[k].parent==-1) //Hofftree[]中找权值最小的两个结点 { if(Hofftree[k].weight<min1) //只在尚未构造二叉树的节点中查找 { min2=min1; rnode=lnode; min1=Hofftree[k].weight; lnode=k; } else if(Hofftree[k].weight<min2) { min2=Hofftree[k].weight; rnode=k; } } Hofftree[i].weight=Hofftree[lnode].weight+Hofftree[rnode].weight; Hofftree[i].lchild=lnode; //Hofftree[i]作为双亲结点 Hofftree[i].rchild=rnode; Hofftree[lnode].parent=i; Hofftree[rnode].parent=i; } } void printHT(HTnode Hofftree[]) //打印哈夫曼树 { int i; printf("哈夫曼树:\n"); printf("weight lchild rchild parent\n"); for(i=0;i<2*n-1;i++) printf("%d\t%d\t%d\t%d\n",Hofftree[i].weight,Hofftree[i].lchild,Hofftree[i].rchild,Hofftree[i].parent); } void Creathcode(HTnode Hofftree[],Hcode hcd[]) //求哈夫曼编码 { int i,f,c,j; Hcode hc; for(i=0;i<n;i++) { hc.start=n; c=i; f=Hofftree[i].parent; while(f!=-1) //循环直到根节点 { if(Hofftree[f].lchild==c) //当前节点是双亲结点的左孩子结点 hc.cd[hc.start--]='0'; else hc.cd[hc.start--]='1'; //当前节点是双亲结点的右孩子结点 c=f; //再对双亲结点做同样的操作 hcd[i]=hc; f=Hofftree[f].parent; //start指向哈夫曼编码的最开始字符 } hc.start++; hcd[i]=hc; } for(i=0;i<n;i++) { printf("%c的编码为\n",info[i].ch); for(j=hcd[i].start;j<=n;j++) printf("%c",hcd[i].cd[j]); printf("\n"); } } int main() { Count(); //统计所输入字符串中字母总个数以及各个字母的个数 CreatHT(Hofftree); //构造哈夫曼树 printHT(Hofftree); //打印哈夫曼树 Creathcode(Hofftree,hcd); //求哈夫曼编码 }
相关文章推荐
- Android Google Map学习一(获取最近一次的位置)
- MSSQLserver中用convert函数转换日期格式
- 表单元素 开篇
- align="absmiddle" 的意义
- MyBatis(增删改查)
- 判断js对象的数据类型,有没有一个最完美的方法?
- vs2010调试技巧
- 华为oj 汽水瓶
- CentOS上安装Docker
- CISCO ACL 增删改
- Android 用adb pull或push 拷贝手机文件到到电脑上,拷贝手机数据库到电脑上,拷贝电脑数据库到手机上
- calerdar的使用
- php通过urlencode转码传到前端,用js解码后特殊字符无法解码
- 递归与循环比较
- python浅拷贝与深拷贝
- controller调用service接口 空指针异常
- POJ 3017 单调队列dp
- 常用的开源框架
- jQuery-1.9.1源码分析系列完毕目录整理
- java.lang.NoSuchMethodError解决办法