哈夫曼编码——编码器,译码器

编码器  译码器  源码实现  

 (1) 对26个小写字母和空格进行赫夫曼编码 ;
              (自己假设字符的频率)
    (2) 编码:输入一个英文句子,输出其编码;
    (3) 译码:输入一个01序列,输出原文

#include<stdio.h>
#include<math.h>
#include<string.h>
#include<stdlib.h>
#define N 27
#define TYPE int
typedef struct
{
  TYPE w;
  int f,l,r;
}HNode,*Htree;
typedef struct
{
  char c;
  char code[10];
}Hcode, *Huffman;

void creat_HuffmanTree(HNode HT[],char ch[],int n1 )//n1为树节点数
{
  int i,j;
  TYPE low1,low2;
  int p1=0,p2=0;        //初始化p1,p2
  for ( i=N+1; i<=n1; i++ )
  {
    low1=999,low2=999;
    for ( j=1;j<i;j++)
    {
      
      if ( HT[j].f==0 && HT[j].w<low1)
      {
        low1=HT[j].w;
        p1=j;
      }    
    }
    for ( j=1;j<i;j++)
      if ( HT[j].f==0 && HT[j].w<low2 &&  j!=p1 )
      {
        low2=HT[j].w;
        p2=j;
      }
       
    HT[p1].f=i;   
    HT[p2].f=i;    
    HT[i].l=p1;    
    HT[i].r=p2;    
    HT[i].w=low1+low2; 
  }
}
void creat_Huffmancoding( HNode HT[],Hcode HC[],char ch[],int n1,int n2)//n1为树节点数,n2为符号个数
{             //左1右0
  int i,j,m,ff;
  char tmp[20];
  for ( i=1;i<=n2;i++ )
  {
    ff=i;
    j=0;   
    while ( HT[ff].f!=0 )
    {
     
      if ( HT[ HT[ff].f ].l==ff)
        tmp[j++]='1';
      else tmp[j++]='0';
      ff=HT[ff].f;
    }
    tmp[j]='\0';
    HC[i].c =ch[i];      //字符下标从1开始
    for ( m=0;m<j;m++ )
      HC[i].code[m]=tmp[j-1-m];
    HC[i].code[m]='\0';
  }
}
void ECode(Hcode HC[])
{
  int i=0,j;
  char ss[100];
  gets(ss);
  while ( i<(int)strlen(ss) )
  {
    for ( j=1;j<=N;j++ )  //N为HC下标
     if (HC[j].c==ss[i])
     {
      printf ("%s ",HC[j].code);
      break;
     }
     if (j>N)
      printf ("ERROR ");
    i++;
  }
  printf ("\n");  

}
void DCode(Hcode HC[N+1])
{
  char ss[100];
  int i,j,m,k[N+1]={0},maxlen=0,tmp[N+1][N+1]={0};//tmp   几位字符,存放地址
  int begin,l,flag;
  char st[N+1];
  for ( i=1;i<=N;i++ )
  {
    j=strlen(HC[i].code);
    tmp[j][k[j]++]=i;
    if (j>maxlen)
     maxlen=j;
  }
  gets(ss);
  for ( begin=0;begin<(int)strlen(ss);)
  {
     for ( flag=l=0,j=begin;j<begin+maxlen;j++,l++ )
     {
     st[l]=ss[j];
     st[l+1]='\0'; 
     for ( m=0;m<k[j-begin+1];m++ )
     if (memcmp(st,HC[tmp[j-begin+1][m]].code,strlen(st) )==0)
     {
       printf ("%c",HC[tmp[j-begin+1][m]].c);
       flag=1;
       break;
     }
     if (flag==1){
          begin+=l+1;
          break;
        }
     }
    if (flag==1) flag=0;
     else printf("ERROE ");
  }
  printf ("\n");
}
int main()
{
  int i,k;
  char ch[N+1]={'0','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',' '};
  TYPE n[N]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27};         //默认权值
  HNode HT[2*N];
  Hcode HC[N+1]; 
  
  

  for ( i=1;i<=N;i++ )
  {
    HT[i].w=n[i-1];     
  }
  for ( i=1;i<=2*N;i++)      //结构体数据f,l,r,w初始化
   HT[i].f=HT[i].l =HT[i].r =0;

  creat_HuffmanTree (HT,ch,2*N-1);
  creat_Huffmancoding (HT,HC,ch,2*N-1,N);
  printf ("________________最短编码__________________________________________\n");
  printf ("_____1· 26个小写字母和空格进行赫夫曼编码_____________________________\n");
  printf ("_____2· 输入一个英文句子,输出其编码    _______________________________\n");
  printf ("_____3· 输入一个01序列,输出原文        ________________________________\n");
  printf ("_________________________________________________________________\n");
        printf ("输入序列号:");
  while(scanf ("%d",&k)&&  k!=0)
  { getchar();
   switch (k)
   {
   case 1:for ( i=1;i<=N;i++)
       {
      printf ("%c  %8s\t",HC[i].c,HC[i].code);
      if (!i%5)printf ("\n");
       }printf ("\n");
     break;
   case 2:ECode(HC);break;
   case 3:DCode(HC);break;
   default:        break;
  
  
   }
  }
  
  return 0;
}

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值