温习 数据结构之HuffmanTree

一定要亲自试了,才会印象深刻呢!!!

//HuffmanTree

#include<stdio.h>
#include<string.h>
#include<malloc.h>
#define UNIT_MAX 10000
typedef struct
{
   unsigned int weight;
   unsigned int parent,lchild,rchild;
}HTNode,*HuffmanTree; //动态分配数组存储HuffmanTree
typedef char **HuffmanCode;//动态分配数组存储HuffmanCode

int min1(HuffmanTree t,int i)
{//函数VOID select调用
   int j,flag;
   unsigned int k=UNIT_MAX;//取K为最小可能的值
   for(j=1;j<=i;j++)
     if(t[j].weight<k && t[j].parent==0)
        {
           k=t[j].weight;
           flag=j;
        }
        t[flag].parent=1;
        return flag;
}

void select(HuffmanTree HT,int i,int *s1,int *s2)
{
   int j;
   *s1=min1(HT,i);
   *s2=min1(HT,i);
   if(*s1>*s2)
   {
       j=*s1;
      *s1=*s2;
      *s2=j;
   }
}
void HuffmanCoding(HuffmanTree *HT,HuffmanCode *HC,int *w,int n)   //这里也是必须用两个*,我开始以为不用的呢。。。
{//w存放n个字符的权值(>0),构造哈弗曼树HT,并求出n个字符的哈弗曼编码HC、
  int m,i;
  HuffmanTree p;
 if(n<=1) return ;
  m=2*n-1;
  *HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));  //0号单元未用
  for(p=*HT+1,i=1;i<=n;++i,++p,++w)
  {
    p->weight=*w;
    p->parent=0;
    p->lchild=0;
    p->rchild=0;
  }
  for(;i<=m;++i,++p)
  {
    p->weight=0;
    p->parent=0;
    p->lchild=0;
    p->rchild=0;
  }
  for(i=n+1;i<=m;++i)//建HuffmanTree
  {//在HT[1..i-1]中选择parent为0且weight最小的两个节点,其序号分别为s1,s2.
     int s1,s2;
     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;
  }
    //-------------从叶子到根逆向求每个字符的HuffmanCode--------
    *HC=(HuffmanCode)malloc((n+1)*sizeof(char*));  //分配n个字符编码的头指针向量
     char *cd;
	cd=(char*)malloc(n*sizeof(char));
     cd[n-1]='\0';  
    //分配求编码的工作空间
    for(i=1;i<=n;++i)
    { 
	int start=n-1;
       int f,c;
       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';
       (*HC)[i]=(char*)malloc((n-start)*sizeof(char));  //为第i个字符编码分配空间
       strcpy((*HC)[i],&cd[start]);      //从cd复制编码串到HC  这个超经典啊 为什么要用个&!!
	}
     free(cd);
}//HuffmaCoding
int main()
{
   HuffmanTree HT;
   HuffmanCode HC;
   int *w,n,i;
   printf("请输入权值的个数(>1):");
   scanf("%d",&n);
   w=(int*)malloc(n*sizeof(int));//为数据开辟空间
   printf("请依次输入%d个权值(整型):\n",n);
   for(i=0;i<=n-1;i++)
     scanf("%d",w+i);
   HuffmanCoding(&HT,&HC,w,n);
   for(i=1;i<=n;i++)
     puts(HC[i]);
    return 0;
}

  

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值