哈夫曼树的构造,编码,译码

本文介绍了一种基于哈夫曼树的编码方法实现过程,包括哈夫曼树的创建、编码规则的生成及编码解码操作。通过具体示例展示了如何用C语言构建哈夫曼树,并为每个字符分配最优前缀编码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

////////////////////////////////////////////////////////////////////////////////////
#include<stdio.h>
#include<string.h>
#define MAX 3
typedef struct                                        //////////////////////定义哈夫曼的类型
{
 int  weight;                                      //////////////////////权值
 char data;                                        //////////////////////输入字符
 int  parent,lchild,rchild;                        /////////////////////树的下标
}hufmtree;
////////////////////////////////////////////////////
typedef struct
{
 char ch;                                          ////////////////////字符集的大小为n,则变长编码的长度不会超过n,加上一个结束字符'\0',因此bits的大小可设为n+1
 char bits[MAX+1];
}huffmancode;
//////////////////////////////////////////////////////
void select(hufmtree tree[],int n,int &p1,int &p2)
{
int i;
    p1=p2=1;
while(tree[p1].parent!=0)        //领p1指向未被使用的结点
{p1++;}   
for(i=2;i<=n;i++)          //找出第一个最小权值的值p1
{
    if(tree[i].weight<tree[p1].weight && tree[i].parent==0)
 p1=i;
}
tree[p1].parent=1;          //
while(tree[p2].parent!=0)       //领p2指向未被使用的结点
{p2++;}           //初始p2=p2=1;   当p1=1为最小的时候 p2也只会是1所以要令p2=2开始
for(i=2;i<=n;i++)
{
   
   if(tree[i].weight<tree[p2].weight && tree[i].parent==0)
   p2=i;
}
tree[p2].parent=1;
}


/////////////////////////////////////////////////////
void creathuffman(hufmtree tree[],int n)
{
 int m,i,p1,p2,f;
 char c;
 if(n<=1)
  return;
 m=2*n;
 for(i=1;i<m;i++)                                //
 {
  tree[i].parent=0;                           ///////////////////////////////对数组初始化,下标为0的单元不用
  tree[i].lchild=0;                           //
  tree[i].rchild=0;
  tree[i].weight=0;
 }
 printf("请输入权值和字符\n");
    for(i=1;i<=n;i++)
 {
    scanf("%d,%c",&f,&c);
       tree[i].weight=f;
       tree[i].data=c;
    }
 
 for(i=n+1;i<m;i++)
 {
  select(tree,i-1,p1,p2);                      ////////////////////////////////进行合并,产生n-1个节点
        tree[p1].parent=i;
        tree[p2].parent=i;
  tree[i].lchild=p1;
  tree[i].rchild=p2;
  tree[i].weight=tree[p1].weight+tree[p2].weight;
 }
}
////////////////////////////////////////////////////////////
void print(hufmtree tree[],int n)
{
 int i;
     printf("data     weight    parent    lchild     rchild\n");
 for(i=1;i<=n;i++)
 {
     printf("%3c  %3d  %3d  %3d   %3d\n",tree[i].data,tree[i].weight,tree[i].parent,tree[i].lchild,tree[i].rchild);
 }
}

///////////////////////////////////////////////////////////////
void huffmancoding(hufmtree tree[],huffmancode h[])
{
 
 int start,c,p,i;
 char cd[MAX+1];         ////存放编码的临时变量
 cd[MAX]='\0';
 for(i=1;i<=MAX;i++)
 {
  h[i].ch=tree[i].data;
  start=MAX;
  c=i;
  while(p=tree[c].parent)         //   关键
  {
   if(tree[p].lchild==c)     //
    cd[--start]='0';     //
    else          //
    cd[--start]='1';      //
    c=p;         //
  }           //   关键
     strcpy(h[i].bits,&cd[start]);
   puts(h[i].bits);
   printf("\n");
  
 }
}
////////////////////////////////////////////////////////////////////////////////
void yima(hufmtree tree[], int n )    //////////
{
   int i,p;
   char a[50];
   p=2*n-1;      ///////注意
   printf("请输入编码,就可翻译出字符");
   scanf("%s",a);
   for(i=0;i<=strlen(a);i++)
   {
    if(tree[p].lchild!=0 && tree[p].rchild!=0)
    {
     if(a[i]=='0')
     {p=tree[p].lchild;}  //////////
           else
     {p=tree[p].rchild;}  //////////
    
    }
    if(tree[p].lchild==0)
   {
        printf("%c ",tree[p].data);
     p=2*n-1;
    }
   }
   printf("\n");
}

/////////////////////////////////////////////////////////////////////////////////
int main()
{
   int i=0,f,n;
   char ch;
   hufmtree tree[100];         /////////////这是一个数组
   huffmancode h[MAX];                                ////////////
   printf("请输入节点数\n");
   scanf("%d",&n);
   creathuffman(tree,n);
   print(tree,n);
   huffmancoding(tree,h);
   yima(tree,n);
   return 0;
}
////////////////////////////////////////////////////////////////

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值