赫夫曼编码!
来源:互联网 发布:最靠谱的租房软件 编辑:程序博客网 时间:2024/05/16 14:13
算法描述:
1.为结点(包括叶子结点和根结点)赋值。
设叶子结点有n个,则总结点数有2n-1个。首先为前n个结点,即叶子结点赋值。规定叶子节点的左右孩子均为0,根结点的双亲为0;赋值完叶子结点后从n+1到2n-1为根结点赋值。
2.构造赫夫曼树
首先在n个叶子结点中挑选权值最小的俩个叶子结点,它们的双亲则为第n+1个结点,即第一个子根。并且该双亲的权值等于这两个孩子的权值之和。下一次在n+1个结点中(包括新构造的第一个双亲结点)中再次挑选权值最小的两个结点,去构造第二个双亲结点。。。。以此类推。。
3.进行编码
规定左路赋值为0,右路赋值为1,每个叶子对应的编码则为从根到该结点的路径上所对应的编码。程序中是从结点到根逆序赋值。
- #include<string.h>
- #include<malloc.h> // malloc()等
- #include<limits.h> // INT_MAX等
- #include<stdio.h> // EOF(=^Z或F6),NULL
- //huffman树的存储结构
- typedef struct
- {
- unsigned int weight;//权值
- unsigned int parent,lchild,rchild;//双亲,左右孩子的序号
- }HTNode,*HuffmanTree;
- typedef char **HuffmanCode;
- int min(HuffmanTree t,int i)
- { // 返回i个结点中权值最小的树的根结点序号,函数select()调用
- int j,flag;
- unsigned int k=UINT_MAX; // 取k为不小于可能的值(无符号整型最大值)
- for(j=1;j<=i;j++)
- if(t[j].weight<k&&t[j].parent==0) // t[j]是树的根结点
- k=t[j].weight,flag=j;
- t[flag].parent=1; // 给选中的根结点的双亲赋1,避免第2次查找该结点
- return flag;
- }
- void select(HuffmanTree t,int i,int &s1,int &s2)
- { // 在i个结点中选择2个权值最小的树的根结点序号,s1为其中序号小的那个
- int j;
- s1=min(t,i);
- s2=min(t,i);
- if(s1>s2)
- {
- j=s1;
- s1=s2;
- s2=j;
- }
- }
- void HuffmanCoding(HuffmanTree &HT,HuffmanCode &HC,int *w,int n)
- { // w存放n个字符的权值(均>0),构造赫夫曼树HT,并求出n个字符的赫夫曼编码HC
- int m,i,s1,s2,start;
- unsigned c,f;
- HuffmanTree p;
- char *cd;
- if(n<=1)
- return;
- m=2*n-1;
- HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode)); // 0号单元未用
- for(p=HT+1,i=1;i<=n;++i,++p,++w)
- {
- (*p).weight=*w;
- (*p).parent=0;
- (*p).lchild=0;
- (*p).rchild=0;
- }
- for(;i<=m;++i,++p)
- (*p).parent=0;
- for(i=n+1;i<=m;++i) // 建赫夫曼树
- { // 在HT[1~i-1]中选择parent为0且weight最小的两个结点,其序号分别为s1和s2
- select(HT,i-1,s1,s2);
- HT[s1].parent=HT[s2].parent=i;
- HT[i].lchild=s1;
- HT[i].rchild=s2;
- HT[i].weight=HT[s1].weight+HT[s2].weight;
- }
- // 从叶子到根逆向求每个字符的赫夫曼编码
- HC=(HuffmanCode)malloc((n+1)*sizeof(char*));
- // 分配n个字符编码的头指针向量([0]不用)
- cd=(char*)malloc(n*sizeof(char)); // 分配求编码的工作空间
- cd[n-1]='\0'; // 编码结束符
- for(i=1;i<=n;i++)
- { // 逐个字符求赫夫曼编码
- start=n-1; // 编码结束符位置
- for(c=i,f=HT[i].parent;f!=0;c=f,f=HT[f].parent)
- // 从叶子到根逆向求编码
- if(HT[f].lchild==c)
- cd[--start]='0';
- else
- cd[--start]='1';
- HC[i]=(char*)malloc((n-start)*sizeof(char));
- // 为第i个字符编码分配空间
- strcpy(HC[i],&cd[start]); // 从cd复制编码(串)到HC
- }
- free(cd); // 释放工作空间
- }
- void main()
- {
- HuffmanTree HT;
- HuffmanCode HC;
- int *w,n,i;
- printf("请输入权值的个数(>1): ");
- scanf("%d",&n);
- w=(int*)malloc(n*sizeof(int));
- printf("请依次输入%d个权值(整型):\n",n);
- for(i=0;i<=n-1;i++)
- scanf("%d",w+i);
- HuffmanCoding(HT,HC,w,n);
- for(i=1;i<=n;i++)
- puts(HC[i]);
- }
- 赫夫曼编码
- 赫夫曼编码
- 赫夫曼编码
- 赫夫曼编码
- 赫夫曼编码
- 赫夫曼编码!
- 赫夫曼编码
- 赫夫曼编码
- 赫夫曼编码
- 赫夫曼编码
- 赫夫曼编码
- 赫夫曼编码
- 赫夫曼编码
- 赫夫曼编码
- 赫夫曼编码
- 赫夫曼编码
- 赫夫曼编码
- 赫夫曼编码
- Unity3D Animation动画视图_脚本控制(2)
- 优化SQL Server的内存占用之执行缓存
- 认识VFS
- Apache配置详解(最好的APACHE配置教程)
- android 项目编码修改, GBK 变UTF-8
- 赫夫曼编码!
- ssl_Client
- ftrace 简介
- 什么是UPnP?
- 图解:win7+vs2010+opencv2.3.1配置方法
- linux 下飞鸽(g2ipmsg)的安装
- IC学习笔记(五)
- wordpress在IIS7.5下伪静态处理
- Android---->Allapps加载流程详解【AndroidICS4.0——>Launcher系列五】