简单理解哈夫曼树的构建

/*将所有元素按顺序构造队列,队首为权值最小的结点,它的后继为次最小结点,选中队首和次最小结点将它合并,从队列中删除,并
按顺序插入到队列中,重复操作直至队列里只剩下最后一个结点,构造哈夫曼树完毕*/
 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进栈,到叶结点即完成一个字符的编码,
回溯时将栈顶元素弹出。*/


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值