第11周 项目1 (哈弗曼编码的算法验证)

问题及描述:

  1. #ifndef HEAD_H_INCLUDED  
  2. #define HEAD_H_INCLUDED  
  3. #include <stdio.h>  
  4. #include <string.h>  
  5.   
  6. #define N 50        //叶子结点数  
  7. #define M 2*N-1     //树中结点总数  
  8.   
  9. //哈夫曼树的节点结构类型  
  10. typedef struct  
  11. {  
  12.     char data;  //结点值  
  13.     double weight;  //权重  
  14.     int parent;     //双亲结点  
  15.     int lchild;     //左孩子结点  
  16.     int rchild;     //右孩子结点  
  17. } HTNode;  
  18.   
  19. //每个节点哈夫曼编码的结构类型  
  20. typedef struct  
  21. {  
  22.     char cd[N]; //存放哈夫曼码  
  23.     int start;  
  24. } HCode;  
  25. void CreateHT(HTNode ht[],int n);  
  26. void CreateHCode(HTNode ht[],HCode hcd[],int n);  
  27. void DispHCode(HTNode ht[],HCode hcd[],int n);  
  28. #endif // HEAD_H_INCLUDED  

[html]  view plain  copy
  1. #include"head.h"  
  2. int main()  
  3. {  
  4.     int n=8,i;      //n表示初始字符串的个数  
  5.     char str[]= {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'};  
  6.     double fnum[]= {0.07,0.19,0.02,0.06,0.32,0.03,0.21,0.1};  
  7.     HTNode ht[M];  
  8.     HCode hcd[N];  
  9.     for (i=0; i<n; i++)  
  10.     {  
  11.         ht[i].data=str[i];  
  12.         ht[i].weight=fnum[i];  
  13.     }  
  14.     printf("\n");  
  15.     CreateHT(ht,n);  
  16.     CreateHCode(ht,hcd,n);  
  17.     DispHCode(ht,hcd,n);  
  18.     printf("\n");  
  19.     return 0;  
  20. }  

[html]  view plain  copy
  1. #include"head.h"  
  2. void CreateHT(HTNode ht[],int n)  
  3. {  
  4.     int i,k,lnode,rnode;  
  5.     double min1,min2;  
  6.     for (i=0; i<2*n-1; i++)         //所有结点的相关域置初值-1  
  7.         ht[i].parent=ht[i].lchild=ht[i].rchild=-1;  
  8.     for (i=n; i<2*n-1; i++)         //构造哈夫曼树  
  9.     {  
  10.         min1=min2=32767;            //lnode和rnode为最小权重的两个结点位置  
  11.         lnode=rnode=-1;  
  12.         for (k=0; k<=i-1; k++)  
  13.             if (ht[k].parent==-1)   //只在尚未构造二叉树的结点中查找  
  14.             {  
  15.                 if (ht[k].weight<min1)  
  16.                 {  
  17.                     min2=min1;  
  18.                     rnode=lnode;  
  19.                     min1=ht[k].weight;  
  20.                     lnode=k;  
  21.                 }  
  22.                 else if (ht[k].weight<min2)  
  23.                 {  
  24.                     min2=ht[k].weight;  
  25.                     rnode=k;  
  26.                 }  
  27.             }  
  28.         ht[i].weight=ht[lnode].weight+ht[rnode].weight;  
  29.         ht[i].lchild=lnode;  
  30.         ht[i].rchild=rnode;  
  31.         ht[lnode].parent=i;  
  32.         ht[rnode].parent=i;  
  33.     }  
  34. }  
  35.   
  36. //实现哈夫曼编码  
  37. void CreateHCode(HTNode ht[],HCode hcd[],int n)  
  38. {  
  39.     int i,f,c;  
  40.     HCode hc;  
  41.     for (i=0; i<n; i++) //根据哈夫曼树求哈夫曼编码  
  42.     {  
  43.         hc.start=n;  
  44.         c=i;  
  45.         f=ht[i].parent;  
  46.         while (f!=-1)   //循序直到树根结点  
  47.         {  
  48.             if (ht[f].lchild==c)    //处理左孩子结点  
  49.                 hc.cd[hc.start--]='0';  
  50.             else                    //处理右孩子结点  
  51.                 hc.cd[hc.start--]='1';  
  52.             c=f;  
  53.             f=ht[f].parent;  
  54.         }  
  55.         hc.start++;     //start指向哈夫曼编码最开始字符  
  56.         hcd[i]=hc;  
  57.     }  
  58. }  
  59.   
  60. //输出哈夫曼编码  
  61. void DispHCode(HTNode ht[],HCode hcd[],int n)  
  62. {  
  63.     int i,k;  
  64.     double sum=0,m=0;  
  65.     int j;  
  66.     printf("  输出哈夫曼编码:\n"); //输出哈夫曼编码  
  67.     for (i=0; i<n; i++)  
  68.     {  
  69.         j=0;  
  70.         printf("      %c:\t",ht[i].data);  
  71.         for (k=hcd[i].start; k<=n; k++)  
  72.         {  
  73.             printf("%c",hcd[i].cd[k]);  
  74.             j++;  
  75.         }  
  76.         m+=ht[i].weight;  
  77.         sum+=ht[i].weight*j;  
  78.         printf("\n");  
  79.     }  
  80.     printf("\n  平均长度=%g\n",1.0*sum/m);  
  81. }  

运行结果:






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值