Huffman编码算法的实现

本文介绍了Huffman编码的数据结构设计,包括Huffman树中没有度为1的节点的特性,以及1棵树有n个叶子节点时共有2n-1个节点的存储策略。接着详细阐述了Huffman编码的生成过程,提供了两种不同的方法,一种是从叶子节点到根的逆向处理,另一种是从根节点开始遍历。最后,讨论了求编码的方法,强调了编码的唯一性和最大长度,并给出了代码实现的提示。
摘要由CSDN通过智能技术生成

1.数据结构设计


Huffman树中没有度为1的节点。n0=n2+1;
1棵树有n个叶子节点的Huffman树共有2n-1个节点,故可存储在大小为2n-1的一位数组中。
原因:
求编码需要从叶子节点出发走一条从叶子到根的路径。

WeightParentLchildRchild
权值双亲节点下标

  译码需从根节点出发走一条到叶子结点的路径。

2.结构定义

typedef struct htnode
{
	unsigned int Weight;
	unsigned int Parent,Lchild,Rchild;
    
}HTNode;

3.Huffmand的生成

//Huffmand的生成
void Create_Huffman(unsigned n,HTNode HT[],unsigned m){
	/*创建一颗叶子结点树为n的Huffman树*/
	unsigned int w;int k,j;
	for(k=1;k<m;k++){
		if(k<=n){
			cout<<"\nPlease Input Weight :w=?";
			cin>>w;
			HT[k].Weight=w;
		}/*输入时,所有叶子结点都有权值*/
		else
			HT[k].Weight=0;/*非叶子结点没有权值*/
		HT[k].Parent=HT[k].Lchild=HT[k].Rchild=0; 
	}//初始化向量HT
	for(k=n+1;k<m;k++){
		unsigned w1=32564,w2=w1;
				/*w1,w2分别保存权值最小的两个权值*/
		int p1=0,p2=0;
		       /*p1,p2保存两个最小权值的下标*/
		for(j=1;j<=k-1;j++){
			if(HT[k].Parent==0){/*尚未合并*/
				if(HT[j].Weight<w1){
					w2=w1;p2=p1;
					w1=HT[j].Weight;
					p1=j;
				}
				
				else if(HT[j].Weight<w2){
					w2=HT[j].Weight;
					p2=j;
				}		/*找到权值最小的两个值及其下标*/		
			}	 	 
		} 
		HT[k].Lchild=p1;HT[k].Rchild=p2;
		HT[k].Weight=w1+w2;
		HT[p1].Parent=k;HT[p2].Parent=k;
	} 
	
} 

 根据出现的频度(权值)Weight,对叶子节点的Huffman编码有两种方式:
    (1)从叶子节点到根逆向处理 ,求得每个叶子结点对于字符的Huffman编码。 
    (2)从根节点开始遍历整颗二叉树,求得每个叶子 节点对应字符的Huffman编码。
    
 由Huffman树生成知,n个叶子结点的树共有2n-1个结点,叶子结点存储在数组HT中下标值为1-n.
     (1)编码是叶子结点的编码,只需对数组HT[1...n]的n个权值进行编码。
     (2)每个字符的编码不同,但编码的最大长度是n。 


4.求编码

求编码时先设置一个通用的字符的指针变量,求得编码后再复制。

代码:

void Huff_coding(unsigned n,Hnode HT[],unsigned m)
	/*m应为n+1,编码的最大长度n加1*/
	{
		int k,sp,fp;
		char *cd,*HC[m];
		cd=(char *)malloc(m*sizeof(char));
		     /*动态分配求编码的工作空间*/
		cd[n]='\0';
		for(k=1;k<n+1;k++)/*逐个求字符的编码*/{
			sp=n;p=k;fp=HT[k].parent;
			for(;fp!=0;p=fp,fp=HT[p].parent)
					/*从叶子结点到根逆向求编码*/ 
				if(HT[fp].parent==Lchild) cd[--sp]='0' ;
				else cd[--sp]='1';
			HC[k]=(char *)malloc((n-sp)*sizeof(char));
				/*为第k个字符分配保存编码的空间*/
			trcpy(HC[k],&cd[sp]); 
		} 
		free(cd);
	} 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值