/*
*哈夫曼编码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;
}
哈夫曼树C语言
最新推荐文章于 2022-10-23 13:39:38 发布