对26个英文字母进行huffman编码
来源:互联网 发布:excel中找出相同数据 编辑:程序博客网 时间:2024/05/16 00:50
<ol><li class="alt"><span><span class="comment">1、建立哈夫曼树</span> </span></li><li><span><span class="comment">2、从每个叶结点回溯到root的路径,并记录路径,则为哈夫曼编码</span> </span></li><li class="alt"><span><span class="comment">3、查表方式获得每个字符的哈夫曼编码</span> </span></li></ol>
#include <stdio.h>#include <stdlib.h>#include <string.h>///----------------------定义结点数据---------------#define leave 26#define node (26*2-1)typedef struct nodee{ char character; float weight; int lson; int rson; int par;}Node,*pnode;typedef struct code{ int hufcode[leave];///叶节点最长编码位数应该为树的最长路径 ,储存编码结果 int sta; ///编码起始位(相对编码数组) char Char; ///编码的字符值}Code,*pcode;///----------------------构造哈夫曼树----------------void huffman(Node ht[],float wt[]){ int i,j,x1,x2; float min1,min2;///初始化结点数组ht ,即对huffman树进行初始化 for(i=0;i<node;i++) { ht[i].par=-1; ht[i].lson=-1; ht[i].rson=-1; if(i<leave) { ht[i].weight=wt[i]; ht[i].character=i+65;///A-Z的ASCii码 } else { ht[i].weight=0; ht[i].character='?';///生成的中间结点字符值标记为'?' } }///控制n-1次结点的结合(若有n个叶结点) for(i=1;i<leave;i++) { min1=min2=100;///min1、min2记录当前最小、次小权值 x1=x2=0; ///x1、x2记录当前最小次小权值结点的位置(数组标号) for(j=0;j<leave-1+i;j++) ///在[0-j]范围内找最小次小权值结点 { if(ht[j].par==-1 && ht[j].weight<min1)///parent元素的判断是为了排除已结合过的结点,结合过的结点parent有正值 { min2=min1;///当前结点权值小于最小值,所以当前结点变成最小权值结点,原最小结点变成原来的次小结点 x2=x1; min1=ht[j].weight; x1=j; } else { if(ht[j].par==-1 && ht[j].weight<min2) ///当前结点权值大于最小值,小于次小值,则取代次小结点 { min2=ht[j].weight; x2=j; } } } ///将找到的最小、次小权值结点结合成树,为其父结点赋值,可见该哈夫曼树的根节点应该是ht数组最后一个结点ht[node-1] ht[x1].par=leave-1+i; ht[x2].par=leave-1+i; ht[leave-1+i].weight=ht[x1].weight+ht[x2].weight; ht[leave-1+i].lson=x1; ht[leave-1+i].rson=x2; }}///--------------------获取并保存每个叶节点的哈夫曼编码供解码时查询--------------------------void codeht(Node ht[],Code hc[]){ int i,j,d,p; Code x;///依次每个叶结点(在哈夫曼结点数组的最前面的空间中)寻找双亲直到root,记录路径,路径就是哈夫曼编码 for(i=0;i<leave;i++)///从每个字母都向上找寻根节点,使得整个树完整的编码 { x.Char=ht[i].character; x.sta=leave-1;///默认编码起点为编码数组最后一位 d=i; p=ht[i].par; while(1) { if(ht[p].lson == d) x.hufcode[x.sta]=0;///默认编码为左0右1 else if(ht[p].rson==d) x.hufcode[x.sta]=1; else printf("ERROR!!"); d=p; p=ht[d].par;///继续向着根延伸编码 if(p==-1)break;///到了26个字母以外停止,ht[i]为root结点退出循环,说明已经回溯到了根结点 x.sta--; } for(j=x.sta;j<leave;j++) { hc[i].hufcode[j]=x.hufcode[j]; } hc[i].sta=x.sta; hc[i].Char=x.Char; }}///--------------------输出每个字符的的哈夫曼编码------------------------void printcode(Code hc[]){ int i,j; for(i=0;i<leave;i++) { printf("字母%c的huffman编码为:",hc[i].Char); for(j=hc[i].sta;j<leave;j++) { printf("%d",hc[i].hufcode[j]); } printf("\n"); }}///-----------------------查询字符的编码---------------------------void findcode(Code hc[]){ int i,j; char x; printf("请输入一个大写英文字母:"); while(scanf("%c",&x)!=EOF) { getchar(); for(i=0;i<leave;i++) { if(x==hc[i].Char) { printf("字符%c的huffman编码为:",x); for(j=hc[i].sta;j<leave;j++) { printf("%d",hc[i].hufcode[j]); } printf("\n"); } } printf("请输入一个大写英文字母:"); }}///---------------------主函数-----------------------int main(){ Node huftree[node];///存放所有结点数据 Code hcode[leave];///存放所有的编码结果 ///存放叶结点权值 float wt[leave]={0.0856,0.0139,0.0297,0.0378,0.1304,0.0289,0.0199,0.0528,0.0627,0.0013,0.0042,0.0339,0.0249,0.0707,0.0797,0.0199,0.0012,0.0677,0.0607,0.1045,0.0249,0.0092,0.0149,0.0017,0.0199,0.0008}; huffman(huftree,wt); codeht(huftree,hcode); printcode(hcode);///调用可以输出所有的字母编码 findcode(hcode); return 0;}
0 0
- 对26个英文字母进行huffman编码
- 使用Huffman方法对字符进行编码
- 求解英文字母的霍夫曼(Huffman)编码
- 利用matlab自带函数对字符串进行Huffman编码
- 构造Huffman树以及对Huffman编码
- HUFFMAN编码进行压缩---【数据结构】
- 输出26个英文字母
- 随机生成10个英文字母,进行判断
- Huffman对文件编码和解码
- 汇编->显示26个英文字母
- 爱情与26个英文字母
- 随机生成26个英文字母
- PHP 26个英文字母递增
- Python3 打印26个英文字母
- 根据26个英文字母排序
- Huffman树&&Huffman编码
- huffman编码
- huffman编码
- 使用签名校验可以限制Android设备刷入任意image
- 在一天的24小时之中,时钟的时针、分针和秒针完全重合在一起的时候有几次? 都分别是什么时间?你怎样算出来的?(5分钟-15分钟)
- 屏幕坐标转客户区坐标
- JavaScript中undefined和null的异同
- scala学习笔记
- 对26个英文字母进行huffman编码
- pycallgraph 追踪Python函数内部调用
- 鼠标右键菜单
- 在9个点上画10条直线,要求每条直线上至少有三个点?(3分钟-20分钟)
- C# Excel 行高,列宽,合并单元格,单元格边框线,冻结(转载) - 关于C#操作EXCLE常见操作比较全的
- Android学习的第二周笔记
- 重复性的操作让给计算机执行
- 本地roslaunch远程机器的launch文件
- CodeForces 474F Ant colony 【线段树】【gcd】【二分】