哈夫曼树的构建和求哈夫曼编码

来源:互联网 发布:华为云计算工程师 编辑:程序博客网 时间:2024/05/04 07:25

#include "string.h"
#include "conio.h"
#include "malloc.h"
#include <stdio.h>
#define N 10     /*待编码字符的个数,即树中叶结点的最大个数*/
#define M 2*N-1  /*树中总的结点数目*/
typedef struct{
  unsigned int weight;
  unsigned int parent,lchild,rchild;
}HTNode,*HuffmanTree;  /*树中结点的结构*/

typedef char **HuffmanCode;
int w[]={5,29,7,8,14,23,3,11};
char data[]={'a','b','c','d','e','f','g','h'};

void Select(HTNode ht[],int k,int *s1,int *s2){
/*ht[1…k]中选择parent为,并且weight最小的两个结点
其序号由指针变量s1,s2指向*/
  int i;
  for (i=1;i<=k && ht[i].parent!=0 ;i++);
  *s1=i;
  for (i=1;i<=k;i++)
    if (ht[i].parent==0 && ht[i].weight<ht[*s1].weight) *s1=i;
  for (i=1; i<=k ; i++)
    if (ht[i].parent==0 && i!=*s1) break;
  *s2=i;
  for (i=1;i<=k;i++)
    if ( ht[i].parent==0 && i!=*s1 && ht[i].weight<ht[*s2].weight) *s2=i;
}
void HuffmanCoding(HuffmanTree &ht,HuffmanCode &hc,int n){
/*构造Huffman树ht,并求出n个字符的编码*/
 //先生成n棵二叉树

  int i,j,m,c,f,s1,s2,start;
  m=2*n-1;//总节点数
  ht=(HuffmanTree)malloc((m+1)*sizeof(HTNode));
  for (i=1;i<=m;i++){
   if (i<=n)  ht[i].weight=w[i-1];
   else ht[i].weight=0;
   ht[i].parent=ht[i].lchild=ht[i].rchild=0;
   }
  //哈夫曼算法
for(i=n+1;i<=m;i++){
    Select(ht,i-1,&s1,&s2);
    ht[s1].parent=i;   ht[s2].parent=i;
    ht[i].lchild=s1;   ht[i].rchild=s2;
    ht[i].weight=ht[s1].weight+ht[s2].weight;
  }
  hc=(HuffmanCode)malloc((n+1)*sizeof(char *));
  char *cd=(char *)malloc(n*sizeof(char));
  cd[n-1]='/0';
  for (i=1;i<=n;i++) {
    start=n-1;
    for (c=i,f=ht[i].parent;f;c=f,f=ht[f].parent)
      if (ht[f].lchild==c) cd[--start]='0';
      else cd[--start]='1';
 hc[i]=(char *)malloc((n-start)*sizeof(char));
    strcpy(hc[i],&cd[start]);
}
  free(cd);
}
void main()
{
  HuffmanTree ht;
  HuffmanCode hc;
  int n=8;
  HuffmanCoding(ht,hc,n);
  for(int i=1;i<=n;i++)
   printf("%c:%s/n",data[i-1],hc[i]);
  printf("/n");


}

原创粉丝点击