/*将所有元素按顺序构造队列,队首为权值最小的结点,它的后继为次最小结点,选中队首和次最小结点将它合并,从队列中删除,并
按顺序插入到队列中,重复操作直至队列里只剩下最后一个结点,构造哈夫曼树完毕*/
typedef struct hufftree
{
int weight,data;
struct hufftree *next;
struct hufftree *lchild;
struct hufftree *rchild;
}huff,*btree;
btree front=NULL,rear=NULL; //队首,队尾
int code[128][10]; //保存每个字符的编码
int weight[128]; //记录每个字符的权重,即出现的次数
char ch[128]; //保存字符
void createqueue()
{ //将字符按权重从小到大排列
int i,j,temp;
char c;
for(i=1;i<128;i++)
{
for(j=0;j<128;j++)
{
if(weight[j]>weight[j+1])
{
temp=weight[j],weight[j]=weight[j+1],weight[j+1]=temp;
c=ch[j],ch[j]=ch[j+1],ch[j+1]=c;
}
}
}
//生成队列
for(;i<128;i++)
{
if(font==NULL)
{
font=(btree)malloc(sizeof(huff));
font->data=ch[i],font->weight=weight[i];
font->next=NULL,font->lchild=NULL,font->rchild=NULL;
rear=font;
}
else
{
p=(btree)malloc(sizeof(huff));
p->ler=ch[i],p->wei=weight[i],p->next=NULL;
p->lchild=NULL,p->rchild=NULL;
rear->next=p,rear=p;
}
}建立树林完毕,且以按升序排序,建议weight数组都初始化为0,如果有字符没出现则权重为0,生成树林时先把它们跳过
}
void createhuffman(btree *T){
btree s;
while(1)
{
s=(btree)malloc(sizeof(huff));
s->lchild=font,s->rchild=font->next;//将权值最小和次小结点合并到s下
s->next=NULL;
s->data=-1; //不保存字符信息
s->weight=s->lchild->weight+s->rchild->next->weight; //权重之和
font=font->next->next;
if(font==NULL)
{
//建立完毕
(*T)=s; //哈夫曼树的根结点
break;
}
else
{
insert(s->weight,&s); //把新结点插入到队列中
}
}//endwhile
}
void insert(int weight,btree *t)
{ //将新结点插入到队列中
btree q;
if(weight<font->weight)
{
(*t)->next=font;
font=(*t);
}
else
{
for(q=font;1;q=q->next)
{
if(q==rear)
{
rear->next=(*t),rear=(*t);
break;
}
else if(weight>=q->weight&&weight<q->next->weight)
{
(*t)->next=q->next;
q->next=(*t);
break;
}
}
}
}
/*生成字符编码时,可以用栈的结构和树的遍历,往下到左孩子则0进栈,到右孩子则1进栈,到叶结点即完成一个字符的编码,
回溯时将栈顶元素弹出。*/
简单理解哈夫曼树的构建
最新推荐文章于 2023-05-14 17:43:26 发布