哈夫曼树

#include   <stdio.h>  
  #include   <string.h>  
  #include   <stdlib.h>  
  #include   <malloc.h>  
  #include   <conio.h>  
   
  typedef   struct   {  
  unsigned   int   weight;  
  unsigned   int   parent,lchild,rchild;  
  }   HTNode,*HuffmanTree;  
     /*用来存放哈夫曼编码*/    
  typedef   struct   {  
  unsigned   int   s1;  
  unsigned   int   s2;  
  }   MinCode;  
   
  void   Error(char   *message);  
  char**   HuffmanCoding(HuffmanTree   HT,char**   HC,unsigned   int   *w,unsigned   int   n);  
  MinCode   Select(HuffmanTree   HT,unsigned   int   n);  
   
  void   Error(char   *message)  
  {  
  fprintf(stderr,"Error:%s/n",message);  
  exit(1);  
  }  
   
  char**   HuffmanCoding(HuffmanTree   HT,char**   HC,unsigned   int   *w,unsigned   int   n)  
  {   /*构造哈弗曼树ht,哈夫曼树的编码存放在hc中*/
  unsigned   int   i,s1=0,s2=0;  
  HuffmanTree   p;  
  char   *cd;  
  unsigned   int   f,c,start,m;  
  MinCode   min;  
  if(n<=1)   Error("Code   too   small!");  
  m=2*n-1;  
  HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode)); /*第0个单元未用*/ 
  for(p=HT,i=0;i<=n;i++,p++,w++)  /*初始化N个叶子结点*/
  {  
  p->weight=*w;  
  p->parent=0;  
  p->lchild=0;  
  p->rchild=0;  
  }  
  for(;i<=m;i++,p++)   /*将n-1个非叶子结点初始化为0*/
  {  
  p->weight=0;  
  p->parent=0;  
  p->lchild=0;  
  p->rchild=0;  
  }  
  for(i=n+1;i<=m;i++)  
  {  
  min=Select(HT,i-1);  
  s1=min.s1;  
  s2=min.s2;
  printf("s1=%d,s2=%d /n",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;  
  }  
  printf("HT   List:/n");  
  printf("Number/t/tweight/t/tparent/t/tlchild/t/trchild/n");  
  for(i=1;i<=m;i++)  
  printf("%d/t/t%d/t/t%d/t/t%d/t/t%d/n",  
  i,HT[i].weight,HT[i].parent,HT[i].lchild,HT[i].rchild); 
/*从叶子结点到根结点求每个字符的哈夫曼编码*/
  HC=(char**)malloc((n+1)*sizeof(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!=0;c=f,f=HT[f].parent)   /*从叶子结点到根结点求编码*/
  if(HT[f].lchild==c)   cd[--start]='0';  
  else   cd[--start]='1';
  printf("%d   ",start); 
  HC[i]=(char   *)malloc((n-start)*sizeof(char   *));  /*为第i个字符编码分配空间*/
  strcpy(HC[i],&cd[start]);   /*将当前求出的结点的哈夫曼编码复制到hc中*/
  }  
  free(cd);  
  return   HC;  
  }  
   
  MinCode   Select(HuffmanTree   HT,unsigned   int   n)  
  {  
  unsigned   int   min,secmin;  
  unsigned   int   temp;  
  unsigned   int   i,s1,s2,tempi;  
  MinCode   code;  
  s1=1;s2=1;  
  for(i=1;i<=n;i++)  
  if(HT[i].parent==0)  
  {  
  min=HT[i].weight;  
  s1=i;  
  break;  
  }  
  tempi=i++;
  printf("i==%d,min==%d",i,min); 
  for(;i<=n;i++)  
  if(HT[i].weight<min&&HT[i].parent==0)  
  {  
  min=HT[i].weight;  
  s1=i;  
  }  
  for(i=tempi;i<=n;i++)  
  if(HT[i].parent==0&&i!=s1)  
  {  
  secmin=HT[i].weight;  
  s2=i;  
  break;  
  }  
  for(i=1;i<=n;i++)  
  if(HT[i].weight<secmin&&i!=s1&&HT[i].parent==0)  
  {  
  secmin=HT[i].weight;  
  s2=i;  
  }  
  if(s1>s2)  
  {  
  temp=s1;  
  s1=s2;  
  s2=temp;  
  }  
  code.s1=s1;  
  code.s2=s2;  
  return   code;  
  }  
   
  void   main()  
  {  
  HuffmanTree   HT=NULL;  
  char**   HC=NULL;  
  unsigned   int   *w=NULL;  
  unsigned   int   i,n;  
  printf("Input   n:/n");  
  scanf("%d",&n);  
  w=(unsigned   int   *)malloc((n+1)*sizeof(unsigned   int   *)); /*w为n个字符的权值*/ 
  w[0]=0;  
  printf("Enter   weight:/n");  
  for(i=1;i<=n;i++)  
  {  
  printf("w[%d]=",i);  
  scanf("%d",&w[i]);  
  }  
  HC=HuffmanCoding(HT,HC,w,n);  
  printf("char**:/n");  
  printf("Number/t/tWeight/t/tCode/n");  
  for(i=1;i<=n;i++)  
  printf("%d/t/t%d/t/t%s/n",i,w[i],HC[i]);  
   
  }

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值