哈夫曼树C语言

/*
 *哈夫曼编码52个字母以及空格为例
 */
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define valueSum 54
#define nodeSum valueSum*2-1
typedef struct blockElement{
	int weight;
	int parent;
	int lchild;
	int rchild;
	char value;
}blockElement;
int main(void){
	char **hufmanCode;
	blockElement hufTree[nodeSum];
	int hufNowLength=54;
	int hufNowNode=54;
	//初始化哈夫曼编码空间
	if(1){
		int i;
		hufmanCode=(char**)malloc(sizeof(char*)*valueSum);
		if(!hufmanCode)exit(1);
		for(i=0;i<valueSum;++i){
			*(hufmanCode+i)=(char*)malloc(sizeof(char)*1);
			*(*(hufmanCode+i)+0)='\0';
		}
	}
	//初始化hufTree
	if(1){
	int i;
	char value[valueSum]={
		'e','t','a','o','i','n','s','r','h',
		'l','d','u','c','f','m','w','y','g',
		'p','b','v','k','x','j','q','z',' ',
		'E','T','A','O','I','N','S','R','H',
		'L','D','U','C','F','M','W','Y','G',
		'P','B','V','K','X','J','Q','Z','\n'
	};
	//元素权重一次变大
	//初始化所有的节点的parent lchild rchild
	for(i=0;i<nodeSum;++i){
		hufTree[i].parent=-1;
		hufTree[i].lchild=-1;
		hufTree[i].rchild=-1;
	}
	//初始化节点的元素以及对应的权重
	for(i=0;i<valueSum;++i){
		hufTree[i].weight=54-i;
		hufTree[i].value=value[i];
	}
	}
	//构建哈夫曼树
	if(1){
		int i;
		//选两个权值最小的,选两次,每次选一个最小的,那么选两次最小,一定是两个最小的
		while(1){
		int beforeMin,afterMin;
		for(i=0;i<hufNowLength;++i){
			if(hufTree[i].parent==-1){
				beforeMin=i;
				break;
			}
		}
		for(i=0;i<hufNowLength;++i){
			if(hufTree[i].weight<hufTree[beforeMin].weight&&hufTree[i].parent==-1){
				beforeMin=i;
			}
		}
		hufTree[beforeMin].parent=hufNowLength;
		for(i=0;i<hufNowLength;++i){
			if(hufTree[i].parent==-1){
				afterMin=i;
				break;
			}
		}
		for(i=0;i<hufNowLength;++i){
			if(hufTree[i].weight<hufTree[afterMin].weight&&hufTree[i].parent==-1){
				afterMin=i;
			}
		}
		hufTree[afterMin].parent=hufNowLength;
		hufTree[hufNowLength].lchild=beforeMin;
		hufTree[hufNowLength].rchild=afterMin;
		hufTree[hufNowLength].weight=hufTree[beforeMin].weight+hufTree[afterMin].weight;
		if(++hufNowLength==nodeSum){
			break;
		}
	    }
	}
	/*
	输出哈夫曼编码
	从[0]->[53]每次直到根节点结束
	*/
	if(1){
		int processNow=0,before,after;
		while(1){
			int stringlength=strlen(*(hufmanCode+processNow));
			before=processNow;
			after=hufTree[before].parent;
			while(1){
				if(hufTree[after].lchild==before){
					*(hufmanCode+processNow)=(char*)realloc(*(hufmanCode+processNow),sizeof(char)*stringlength+2);
					*(*(hufmanCode+processNow)+stringlength)='0';
					*(*(hufmanCode+processNow)+(stringlength+1))='\0';
					stringlength++;
				}else if(hufTree[after].rchild==before){
					*(hufmanCode+processNow)=(char*)realloc(*(hufmanCode+processNow),sizeof(char)*stringlength+2);
					*(*(hufmanCode+processNow)+stringlength)='1';
					*(*(hufmanCode+processNow)+(stringlength+1))='\0';
					stringlength++;
				}
				before=after;
				after=hufTree[after].parent;
				if(after==-1){
					break;
				}
			}
			processNow++;
			if(processNow==valueSum){
				break;
			}
		}
	}
	//反转所有现有的编码,全部字符转进行Reverse就是相应的哈夫曼编码
	if(1){
		int i,before,after;
		char temp;
		for(i=0;i<valueSum;++i){
			before=0;
			after=strlen(*(hufmanCode+i))-1;
			while(1){
				temp=*(*(hufmanCode+i)+before);
				*(*(hufmanCode+i)+before)=*(*(hufmanCode+i)+after);
				*(*(hufmanCode+i)+after)=temp;
				++before;
				--after;
				if(before>=after){
					break;
				}
			}
		}
	}
	if(1){
		int i,j;
		for(i=0;i<valueSum;++i){
			printf("[%d] value->%c key:",i,hufTree[i].value);
			for(j=0;j<strlen(*(hufmanCode+i));++j){
				printf("%c",*(*(hufmanCode+i)+j));
			}
			printf("\n");
		}
	}
	return 0;
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

高万禄

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值