哈夫曼树构造 哈夫曼编码得到

#define n 4                   //n叶子节点
#define m 2*n-1               //m总的节点
#define infinity 32767

struct node  //哈夫曼树上每个节点
{
 float weight;
 int plink,llink,rlink;
};

struct codetype
{
 int start;      //编码的开始位置
 char bits[n+1]; //编码的长度
};

struct element
{
 char symbol;
 codetype code;
};

node tree[m+1];
element table[n+1];

//一趟循环下来,得到最小而且没有plink的两个值的索引
void select(int s,int &x1,int &x2)
{
 int i;
 float v1,v2;
 v1 = v2 = infinite; //v1,v2记录最小的两个元素的值
 x1 = x2 = 0;  //x1,x2记录最小的两个元素的位置

 for(int i=0;i<=s;i++)
 {//一趟循环下来,得到最小而且没有plink的两个值的索引
  if(tree[i].plink == 0)
  {//如果这个节点还没有弄到哈夫曼树中
   if(tree[i].weight<v1)
   {//v1比v2小
    v2 = v1;
    v1 = tree[i].weight; //得到v1,v2还是最小的两个
    //索引
    x2 = x1;
    x1 = i;

   }
   else if(tree[i].weight <v2)
   {//v1<x<v2,v1不变化,仅仅v2变化
    v2 = tree[i].weight;
    x2 = i;
   }
  }
 }

}

//建立哈夫曼树 1..n是叶子节点,n+1..m是建立的节点
//结果就是从1..n是叶子节点,n+1到m是n2,其中n+1..m是依次建立的。m就是根节点
void setthuftree()
{
 int i;
 int x1,x2;
 for(int i=n+1;i<=m;i++)
 {//n+1..m,建立哈夫曼树
  select(i-1,x1,x2);  //x1,x2是符合条件的最小的两个元素的索引 ,i-1每次都在扩大,从n..m-1
  tree[x1].plink = i;
  tree[x2].plink = i;
  tree[i].weight = tree[x1].weight+ tree[x2].weight;
  tree[i].llink = x1;
  tree[i].rlink = x2;
 }
}


//根据建立好的哈夫曼树建立哈夫曼编码
void setthufcode()
{
 int i;
 int s;
 int f;
 codetype c;
 for(int i=1;i<=n;i++)
 {//对于每一个叶子节点进行哈夫曼编码
  c.start = n+1;//因为哈夫曼编码是一个从根到叶子的顺序,所以得到的最靠近叶子节点的编码,实际上是后面的
  s = i; //对tree的第i个元素进行编码
  f = tree[s].plink; //得到第i个元素的父亲节点,然后就要一直遍历到哈夫曼树的根节点

  do
  {
   c.start--;
   if(s == tree[f].llink)
   {//如果是它的左子树
    c.bits[c.start] = '0';
   }
   else
   {//如果是右子树
    c.bits[c.start] =  '1';
   }

   s = f;
   f = tree[f].plink; //继续向根节点移动
  }while(f)

  table[i].code = c; //c已经是编码好的了
 }

}


//哈夫曼过程
void huffman()
{
  int i;
  int j;
  codetype c;
  //初始化
  for(int i= 0;i<n;i++)
  {
  cin>>table[i].symbol>>tree[i].weight;   //最后table的codetype就是构建好的哈夫曼编码
  }

  //对1..n个叶子节点,构建哈夫曼树
  setthuftree();
  //得到哈夫曼code
  setthufcode();

  //输出
  for(int i=1;i<=n;i++)
  {
  cout<<table[i].symbol<<" ";
  c = table[i].code;
  for(j = c.start;j<=n;j++)
  {//输出哈夫曼编码0101...
   cout<<c.bits[j];
  }
  }

}

 

你可能感兴趣的:(哈夫曼树构造 哈夫曼编码得到)