题目:假设用于通信的电文由字符集{a,b,c,d,e,f,g,h,}中的字母构成,这8个字母在电文中出现的 频率分别为:
{0.19, 0.21, 0.02, 0.03, 0.06, 0.07, 0.1, 0.32}.
要求:画出哈夫曼树。
我从课本上面摘抄了一个题目,题目大概是上面这样的,我们这里只是详细的说明一下哈弗曼树要怎么构建。借用一下这个题目。
分析:我们这里直接将小数整数化,容易看出大小来。
(1)8个结点的权值大小如下:
(2)从19,21,2,3,6,7,10,32中选择两个权小结点。选中2,3。同时算出这两个结点的和5。
(3)从19,21,6,7,10,32,5中选出两个权小结点。选中5,6。同时计算出它们的和11。
(4)从19,21,7,10,32,11中选出两个权小结点。选中7,10。同时计算出它们的和17。
注:这时选出的两个数字都不是原来的二叉树里面的结点,所以要另外开一棵二叉树。
(5)从19,21,32,11,17中选出两个权小结点。选中11,17。同时计算出它们的和28。
(6)从19,21,32,28中选出两个权小结点。选中19,21。同时计算出它们的和40。 另起一颗二叉树。
(7)从32,28, 40中选出两个权小结点。选中28,32。同时计算出它们的和60。
(7)从 40, 60中选出两个权小结点。选中40,60。同时计算出它们的和100。 好了,此时哈夫曼树已经构建好了。
ps:上次做作业的时候,我构造哈弗曼树就是一直从剩下的结点里面找权值最小的,然后添加上去,而没有考虑构造出来的"和"权值的大小问题。导致哈夫曼树构造错误!
哈夫曼编码及译码的实现:
- #include<stdio.h>
- #include<string.h>
- #include<stdlib.h>
-
-
- typedef struct
- {
- int weight;
- int parent;
- int lchild;
- int rchild;
- }HTNode,*HuffmanTree;
-
- static char N[100];
-
-
- typedef char **HuffmanCode;
-
-
- typedef struct
- {
- int s1;
- int s2;
- }MinCode;
-
-
- void Error(char *message);
- HuffmanCode HuffmanCoding(HuffmanTree &HT,HuffmanCode HC,int *w,int n);
- MinCode Select(HuffmanTree HT,int n);
-
-
- void Error(char *message)
- {
- fprintf(stderr,"Error:%s\n",message);
- exit(1);
- }
-
-
- HuffmanCode HuffmanCoding(HuffmanTree &HT,HuffmanCode HC,int *w,int n)
- {
- int i,s1=0,s2=0;
- HuffmanTree p;
- char *cd;
- int f,c,start,m;
- MinCode min;
-
- if(n<=1)
- {
- Error("Code too small!");
- }
-
- m=2*n-1;
- HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));
-
-
- for(p=HT,i=0;i<=n;i++,p++,w++)
- {
- p->weight=*w;
- p->parent=0;
- p->lchild=0;
- p->rchild=0;
- }
-
-
- for(;i<=m;i++,p++)
- {
- p->weight=0;
- p->parent=0;
- p->lchild=0;
- p->rchild=0;
- }
-
-
- for(i=n+1;i<=m;i++)
- {
- min=Select(HT,i-1);
- s1=min.s1 ;
- s2=min.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("HT List:\n");
- printf("Number\t\tweight\t\tparent\t\tlchild\t\trchild\n");
-
- for(i=1;i<=m;i++)
- {
- printf("%d\t\t%d\t\t%d\t\t%d\t\t%d\t\n",i,HT[i].weight,HT[i].parent,HT[i].lchild,HT[i].rchild);
- }
-
-
- HC=(HuffmanCode)malloc((n+1)*sizeof(char *));
- 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 *));
-
- strcpy(HC[i],&cd[start]);
- }
- free(cd);
- return HC;
- }
-
- MinCode Select(HuffmanTree HT,int n)
- {
- int min,secmin;
- int temp = 0;
- int i,s1,s2,tempi = 0;
- MinCode code ;
- s1=1;
- s2=1;
-
- min = 66666;
-
-
- for(i=1;i<=n;i++)
- {
- if(HT[i].weight<min && HT[i].parent==0)
- {
- min=HT[i].weight;
- s1=i;
- }
- }
-
- secmin = 66666;
-
-
- for(i=1;i<=n;i++)
- {
- if((HT[i].weight<secmin) && (i!=s1) && HT[i].parent==0)
- {
- secmin=HT[i].weight;
- s2=i;
- }
- }
-
-
- code.s1=s1;
- code.s2=s2;
- return code;
- }
-
- void HuffmanTranslateCoding(HuffmanTree HT, int n,char* ch)
- {
- int m=2*n-1;
- int i,j=0;
-
- printf("After Translation:");
- while(ch[j]!='\0')
- {
- i=m;
- while(0 != HT[i].lchild && 0 != HT[i].rchild)
- {
- if('0' == ch[j])
- {
- i=HT[i].lchild;
- }
- else
- {
- i=HT[i].rchild;
- }
- ++j;
- }
- printf("%c",N[i-1]);
- }
- printf("\n");
- }
-
- void main()
- {
- HuffmanTree HT=NULL;
- HuffmanCode HC=NULL;
- int *w=NULL;
- int i,n;
- char tran[100];
-
- printf("Input N(char):");
- gets(N);
- fflush(stdin);
- n = strlen(N);
-
- w=(int *)malloc((n+1)*sizeof(int *));
- w[0]=0;
- printf("Enter weight:\n");
-
-
- for(i=1;i<=n;i++)
- {
- printf("w[%d]=",i);
- scanf("%d",&w[i]);
- }
- fflush(stdin);
-
- HC=HuffmanCoding(HT,HC,w,n);
-
-
- printf("HuffmanCode:\n");
- printf("Number\t\tWeight\t\tCode\n");
- for(i=1;i<=n;i++)
- {
- printf("%c\t\t%d\t\t%s\n",N[i-1],w[i],HC[i]);
- }
-
- fflush(stdin);
-
- printf("Input HuffmanTranslateCoding:");
- gets(tran);
- HuffmanTranslateCoding(HT, n, tran);
- return;
- }
我们对正文:computer进行哈夫曼编码。权值就用上面的那8个好了。
>>computer
>>19
>>21
>>2
>>3
>>6
>>7
>>10
>>32
运行界面、编码结果及译码结果: