哈夫曼编码C语言

 

参考:《软件设计师考试——考点分析与真题详解》

      我们设置一个结构数组 huffnode 保存哈夫曼树中各结点的信息。根据二叉树的性质可知,具有n个叶子结点的哈夫曼树共有 2n-1 个结点,所以数组 huffnode 的大小设置为 2n-1 。huffnode 结构中有 weight, lchild, rchild 和 parent 域。其中,weight 域保存结点的权值, lchild 和 rchild 分别保存该结点的左、右孩子的结点在数组 huffnode 中的序号,从而建立起结点之间的关系。为了判定一个结点是否已加入到要建立的哈夫曼树中,可通过 parent 域的值来确定。初始时 parent 的值为 -1。当结点加入到树中去时,该结点 parent 的值为其父结点在数组 huffnode 中的序号,而不会是 -1 了。

      求叶结点的编码:

  该过程实质上就是在已建立的哈夫曼树中,从叶结点开始,沿结点的双亲链域回退到根结点,每回退一步,就走过了哈夫曼树的一个分支,从而得到一位哈夫曼码值。由于一个字符的哈夫曼编码是从根结点到相应叶结点所经过的路径上各分支所组成的 0、1 序列,因此先得到的分支代码为所求编码的低位,后得到的分支代码为所求编码的高位码。我们可以设置一个结构数组 huffcode 用来存放各字符的哈夫曼编码信息,数组元素的结构中有两个域:bit 和 start。其中,域 bit 为一维数组,用来保存字符的哈夫曼编码, start 表示该编码在数组 bit 中的开始位置。所以,对于第 i 个字符,它的哈夫曼编码存放在 huffcode[i].bit 中的从 huffcode[i].start 到 n 的 bit 位中。

#include
#include
using namespace std;
int n;
struct huffnotetype
{
  int parent;
  int weight;
  int lchild;
  int rchild;
}huffnote[1005];
struct huffcodetype
{
  int start;
  int bit[505];
}huffcode[1005],cd;
void buildtree()
{
    int i,j;
    int m1,m2,x1,x2;
    for(i=0;i     {
      m1=m2=1000000;//找到两个权值最小的并且没被用过的点
      x1=x2=0;//存储这俩点下标
      for(j=0;j       {
        if(huffnote[j].weight         {
          m2=m1;
          x2=x1;
          m1=huffnote[j].weight;
          x1=j;
        }
        else if(huffnote[j].weight         {
          m2=huffnote[j].weight;
          x2=j;
        }
      }
      huffnote[x1].parent=n+i;
      huffnote[x2].parent=n+i;
      huffnote[n+i].lchild=x1;
      huffnote[n+i].rchild=x2;
      huffnote[n+i].weight=m1+m2;//建立和两个点的父节点
    }
}
void gethuff()//这个部分,读者可以自己建棵哈夫曼树进行模拟一下
{
  int i,j,c,p;
  for(i=0;i   {
    cd.start=n-1;
    c=i;
    p=huffnote[c].parent;//先从最小的叶子节点开始王根结点找
    while(p!=-1)
    {
        if(huffnote[p].lchild==c)
        {
          cd.bit[cd.start]=0;
        }
        else
        {
          cd.bit[cd.start]=1;
        }
        c=p;
        p=huffnote[c].parent;//循环往复,一直找到根节点
        cd.start--;//记录这个节点的编码长度
    }
    for(j=cd.start+1;j     {
      huffcode[i].bit[j]=cd.bit[j];//cd,只是暂时存储,huffcode才是本节点的具体编码信息
    }
    huffcode[i].start=cd.start+1;


  }
}
int main()
{
   int i,j;
   cin>>n;
   for(i=0;i<2*n-1;i++)
   {
     huffnote[i].weight=0;
     huffnote[i].parent=-1;
     huffnote[i].lchild=-1;
     huffnote[i].rchild=-1;
   }//赋初值
   for(i=0;i         scanf("%d",&huffnote[i].weight);
   buildtree();//建树
   gethuff();//得到每个叶子节点的编码值
   for(i=0;i    {
       printf("%d  ",i);
      for(j=huffcode[i].start;j             printf("%d",huffcode[i].bit[j]);
      printf("\n");
   }
}

你可能感兴趣的:(ACM—哈夫曼,ACM,哈夫曼)