哈夫曼树与哈夫曼编码

该博客介绍了如何构建哈夫曼树并进行哈夫曼编码。内容包括根据节点数量输入构建过程,详细展示了如何找到最小两个节点进行合并,并最终得出各字符的哈夫曼编码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include<stdio.h>
typedef struct{ //节点的结构 
	unsigned int weight;
	unsigned int parent,lchild,rchild;
}HTNode,*HuffmanTree;

typedef char **HuffmanCode; //动态分配数组存储哈夫曼编码表

//构造哈夫曼树,并求哈夫曼编码 
HuffmanCode HuffmanCoding(HuffmanTree HT,HuffmanCode HC,int *w,int n){
	HuffmanTree p; 
	int start;
	unsigned f;
	unsigned c;
	char *cd;
	int m,i,j,s1,s2,m1,m2;
	if(n<=1)
		return 0;
	m =  2*n-1; //哈夫曼树共m个节点
	HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode)); /* 0号单元未用  */
	for(p = HT+1,i=1 ;i<=n; ++i,++p,++w){ //从一号到n号开始填表格 
		(*p).weight = *w; //赋权值
		(*p).parent = 0;
		(*p).lchild = 0;
		(*p).rchild = 0;
	} 
	for(;i<=m;++i,++p)
		(*p).parent = 0;  //从i从n+1到m 其余的节点双亲都是0
	//开始建造哈夫曼树
	for(i=n+1;i<=m;++i){
		s1=s2=0;
		m1 = m2 = 10000;
		for(j=1;j<=i-1;j++){
			if(HT[j].weight<m1 && HT[j].parent ==0){
				m2 = m1; s2 = s1;  //s1比s2要小
				m1 = HT[j].weight;  s1 = j; 
			}else if(HT[j].weight<m2 && HT[j].parent==0){
				m2 = HT[j].weight;
				s2 = j;
			}
		}
		printf("\n%d,%d",s1,s2);
		HT[s1].parent = HT[s2].parent = i;
		HT[i].lchild = s1;
		HT[i].rchild = s2;
		HT[i].weight = HT[s1].weight+HT[s2].weight;
	}
	

	//从叶子到根逆向求哈夫曼编码
	HC = (HuffmanCode*)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';
		}
			
		HC[i] = (char*)malloc((n-start)*sizeof(char));//为第i个字符编码分配空间
		strcpy(HC[i],cd+start);  //从cd复制编码到HC  cd+start是什么操作???
			
	} 
	free(cd); 
return(HC); 
}
int main(){
	HuffmanTree HT;
	HuffmanCode HC;
	int *w,n,i;
	printf("please input the n:");
	scanf("%d",&n);
	w = (int*)malloc(n*sizeof(int));//动态生成n个存放权值的空间
	for(i = 0;i<n;i++){
		scanf("%d",w+i);
	} 
	for(i=0;i<n;i++){
		printf("%d    ",w[i]);
	}
	HC = HuffmanCoding(HT,HC,w,n);//把输入的所有权值和共有n个数传进去,构造出哈夫曼树
	for(i=1;i<=n;i++){
		printf("\n %-3d %-8s",w[i-1],HC[i]);  
		//试着换一个逗号 
		
	} 
	 
}
   

 

输入的时候先输入共有多少个节点,在输入节点分别都是什么,输出先输出哈夫曼编码时每次找到最小两个数的序号,最后输出每个字符的哈夫曼编码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值