哈夫曼树实现电文编码译码

哈夫曼编码实现电文字符串编码

  • 电文编码

电文编码

从键盘接收一串电文字符,输出对应的Huffman编码。同时,能翻译由Huffman编码生成的代码串,输出对应的电文字符串

#include
#include
#include
#define MAXSIZE 50
typedef char DataType;

typedef struct	// 哈夫曼树结点的结构
{
     
   DataType data;	// 数据用字符表示
   int weight;	// 权值
   int parent;	// 双亲
   int lchild,rchild;	// 左右孩子
} HuffNode;

typedef struct	// 哈夫曼编码的存储结构
{
     
   DataType cd[MAXSIZE];	// 存放编码位串
   int start;	// 编码的起始位置
} HuffCode;


int HuffmanCreate(HuffNode *ht)
{
     int n=0;
   int i,j,p1,p2,m1,m2;
   char c;

   int frequency[58]={
     0};

   while((c=getchar())!='\n'){
     
      frequency[c-65]++;
   }
   for(int i=0;i<58;i++){
     
      if(frequency[i]!=0){
     
            n++;
         ht[n].data=i+65;
         ht[n].weight=frequency[i];

      }
   }

   for(i=1;i<n+1;i++)
   {
     
         printf("%c" ,ht[i].data);	// 先输出结点
         printf("%d",ht[i].weight);
         printf("\n");
   }
   for(i=1;i<=2*n -1;i++)	// 对数组初始化
      ht[i].parent=ht[i].lchild=ht[i].rchild=0;
   for(i=n+1;i<=2*n-1;i++)
   {
     
      m1=m2=32767;	// 令 m1 、m2 为整数最大值
      p1=p2=1;
      for(j=1;j<i;j++)	//	找出 parent 为 0 且权值最小的两个结点
         {
     
            if(ht[j].parent==0)
            {
     
               if(ht[j].weight<m1)
               {
     
                  m2=m1;
                  p2=p1;
                  m1=ht[j].weight;
                  p1=j;
               }

               else if(ht[j].weight<m2)
               {
     
                  m2=ht[j].weight;
                  p2=j;
               }
            }
         }
         ht[i].lchild=p1;	//p1 为新结点的左孩子
         ht[i].rchild=p2;		//p2	为新结点的右孩子
         ht[i].weight=m1+m2;	//	新结点的权值为最小权值和次小权值的和
         ht[p1].parent=i;
         ht[p2].parent=i;

   }
   for(i=1;i<=n;i++){
     
      printf("此节点%c ,父节点%d ,左孩子 %d,右孩子%d",ht[i].data,ht[i].parent,
             ht[i].lchild,ht[i].rchild);
             printf("\n");
      }
//printf("哈夫曼树已成功建立!	\n");
return n;

}



void Encoding(HuffNode *ht,HuffCode *hcd,int n)
{
     
   HuffCode d;
   int i,j,f;
   for(i=1;i<=n;i++)	// 对所有结点循环
   {
     
      d.start=n+1;	// 起始位置
      f=ht[i].parent; // 双亲的位置
      for(j=i;f!=0;j=f,f=ht[j].parent)
      {
     
         if(ht[f].lchild==j)
            d.cd[ --d.start]='0';	// 规定左树代码为	0
         else
            d.cd[ --d.start]='1';	// 规定右树代码为	1
      }
      hcd[i]=d;
   }
   printf("输出哈夫曼编码:	\n");
   for(i=1;i<=n;i++)
   {
     
      printf("%c" ,ht[i].data);	// 先输出结点
      for(j=hcd[i].start;j<=n;j++)		// 在输出其对应编码
         printf("%c",hcd[i].cd[j]);
      printf("\n");
   }
}


void Decoding(HuffNode *ht,int n)
{
     
   DataType c,ch[200];	//c 接收输入电文,	ch 储存
   int i,temp,f;
   printf("请输入电文,以“#”为结束标志:\n");
   c=getchar();
   i=0;
   while(c!='#')
   {
     
      i++;	//ch 数组下标后移
      ch[i]=c;	// 将单个字符依次存入	ch 字符串中
      c=getchar();
   }
   temp=i;	// 标记数组存储末位位置
   i=1;
   printf("输出哈夫曼译码:	\n");
   while(i<=temp)
   {
     
      f=2*n -1;	// 每次都从根节点开始查找
      while(ht[f].lchild!=0)
      {
     
         if(ch[i]=='0')
            f=ht[f].lchild;
         if(ch[i]=='1')
            f=ht[f].rchild;
         i++;
      }
      printf("%c",ht[f].data);
   }
   printf("\n");
}


void main()
{
     
   int n=0,select;
   char ch;
   HuffNode ht[MAXSIZE*2];	// 定义存放哈夫曼树的数组
   HuffCode hcd[MAXSIZE];	// 定义存放编码的数组
   while(1)
   {
     
      printf( "1---建立哈夫曼树	\n");
      printf( "2---编码   \n");
      printf( "3---译码  \n");
      printf("4---退出系统 	\n");
      printf(" 请输入您所要实现的功能:"	);
      scanf("%d",&select);
      switch(select)
      {
     


         case 1:
               printf("请输入字符串:"	);
               //scanf("%d",&ch);
               getchar();
               n=HuffmanCreate(ht);
               break;
         case 2:
               Encoding(ht,hcd,n);
               break;
         case 3:
               Decoding(ht,n);
               break;
         case 4:
               exit(0);
      }


   }
}

运行结果
哈夫曼树实现电文编码译码_第1张图片
哈夫曼树实现电文编码译码_第2张图片

你可能感兴趣的:(哈夫曼编码,c语言,字符串,数据结构,huffman,tree)