哈夫曼编/译码器

哈夫曼编/译码器

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int MAXN=0x3f3f3f3f;
char* HC[120]; //指针的指针就全局处理,子函数就不用传,方便
struct HtNode
{
    int weight;
    int parent;
    int Lchild;
    int Rchild;
};
typedef struct HtTree
{
    struct HtNode ht[120];
    int root; //root在本到题中,没用
}HtTree,*PHtTree;
void select(PHtTree pht,int pos,int* x1,int* x2)
{
    int  m1=MAXN,m2=MAXN;
    int j;
    for(j=1;j<pos;j++)//pos=n+i,因为不包括自己,所以是<
    {
      if(pht->ht[j].weight<m1&&pht->ht[j].parent==0)
      {
          m2=m1;
          *x2=*x1;      //m2,x2都是存次小的
          m1=pht->ht[j].weight;
          *x1=j;
      }
      else if(pht->ht[j].weight<m2&&pht->ht[j].parent==0)
      {
          m2=pht->ht[j].weight;
          *x2=j;
      }
    }
    return;
}
PHtTree CreateHuffmanTree(int w[],int n)//ht就是huffmantree的缩写。
{
    PHtTree pht;
    int i,x1,x2;
    pht=(PHtTree)malloc(sizeof(HtTree));
    for(i=1;i<=2*n-1;i++)
    {
        pht->ht[i].parent=0;
        pht->ht[i].Lchild=0;
        pht->ht[i].Rchild=0;
        if(i<=n)
        pht->ht[i].weight=w[i];
        else
        pht->ht[i].weight=0;  //一开始所有结点的双亲,子女都为0;
    }
    for(i=1;i<n;i++)
    {
        select(pht,n+i,&x1,&x2); //因为不能返回两个值,所以只能用指针写。
        pht->ht[x1].parent = n + i;
pht->ht[x2].parent = n + i;
pht->ht[n+i].weight = pht->ht[x1].weight
           + pht->ht[x2].weight;
pht->ht[n+i].Lchild = x1;
pht->ht[n+i].Rchild = x2;
pht->root = n+i; //由上而下,逐层建立头结点。
    }
    return pht;
}
void CreHuffmanCode(PHtTree pht,int n) //n就是n个叶子结点
{
    char *cd;
    cd=(char*)malloc(n*sizeof(char)); //因为编码最长也不过log2n;所以长度足够了。
    cd[n-1]='\0';//从右往左逐位存放编码,首先存放编码结束符
    int i,c,p,start;
    for(i=1;i<=n;i++)
    {
        start=n-1;
        c=i;p=pht->ht[i].parent; //提取parent很重要哦。
        while(p!=0)
        {
            --start;  //因为之前cd[n-1]='\0'了,所以一进来,start就要减1;
            if(pht->ht[p].Lchild==c)
            cd[start]='0';//再次强调是从右往左逐位存放编码
            else
            cd[start]='1';
            c=p;p=pht->ht[p].parent;//向上推。
        } //这样就把i的编码给编出来了。
        HC[i]=(char*)malloc((n-start)*sizeof(char));
        strcpy(HC[i],&cd[start]); //注意啊,是取start为下标的地址。所以个数是恰好匹配的
    }
    free(cd);
    return;
}
int main()
{
   int n,i;
   PHtTree pht;
   char s[120];
   char sss[120];
   int w[120];
   scanf("%d",&n);
   getchar();//后面是字符型,所以要吸收这个空格
   for(i=1;i<=n;i++)
   scanf("%c ",&s[i]);
   for(i=1;i<=n;i++)
   scanf("%d",&w[i]);
   getchar();
   gets(sss);
   pht=CreateHuffmanTree(w,n);
   CreHuffmanCode(pht,n);


   int len=strlen(sss);
   for(i=0;i<len;i++)
   {
       printf("%s",HC[sss[i]-'a'+1]);
   }
   printf("\n");
   printf("%s",sss);
   return 0;
}

相关文章:

  • 2021-08-03
  • 2021-07-10
  • 2021-05-06
  • 2021-10-04
猜你喜欢
  • 2022-12-23
  • 2021-12-18
  • 2021-05-10
  • 2021-05-28
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案