#include
#include
#include
#define OVERFLOW -1
typedef struct{
char data;
unsigned int weight;
unsigned int parent,lchild,rchild;
}HTNode, *HuffmanTree;
typedef char** HuffmanCode;
void Select(HuffmanTree T,int n,int&l,int&r)
{
HuffmanTree p=T+1;int a=0,b=0;
for(int i=1;i<=n;++i,++p){
if(!p->parent){
if(!a){l=i;a=1;}
else if(!b){r=i;b=1;}
else if(p->weight<(T+l)->weight||p->weight<(T+r)->weight){
if((T+l)->weight<=(T+r)->weight)r=i;
else l=i;
}
}
}
}
void HuffmanCoding(HuffmanTree &HT, HuffmanCode &HC, int *w, char* c, int n){
if(n<=1) return;
int m = 2*n-1;
HT = (HuffmanTree)malloc((m+1)*sizeof(HTNode));
HuffmanTree p;
int i;
for(p=HT+1,i=1; i<=n; ++i,++p,++w) *p = {c[i-1],*w,0,0,0};
for(i=n+1; i<=m; ++i, ++p) *p = {0,0,0,0,0};
for(i=n+1; i<=m; ++i){
int s1,s2;
Select(HT, i-1, s1, s2);
HT[s1].parent = i; 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 *));
char* cd = (char *)malloc(n*sizeof(char));
cd[n-1] = '\0';
for(i=1; i<=n; ++i){
int start = n-1;
int c,f;
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));
strcpy(HC[i],&cd[start]);
}
free(cd);
}
void PrintHuffmanCode(HuffmanCode HC,int* w,char* c,int n)
{
char *p;
int i;
for(i=1;i<=n;++i){
printf("字符:%c,权重:%3d,编码:", c[i-1], w[i-1]);
p=HC[i];
printf("%s\n",p);
}
}
char* EnCode(HuffmanCode HC, char* c, char ch, int n)
{
int i;
for(i=0;iif(c[i]==ch){
char *p = HC[i+1];
return p;
}
}
}
char* DeCode(const char*s, HuffmanTree HT){
int i; HuffmanTree p=HT;
static char result[500];
int j=0;
while(p->parent!=0) p++;
const HuffmanTree root = p;
for(i=0; i<strlen(s); ++i){
if(s[i]=='0'){
if(p->lchild!=0){
p=HT+p->lchild;
}
}
else if(s[i]=='1'){
if(p->rchild!=0){
p=HT+p->rchild;
}
}
if(p->lchild==0&&p->rchild==0){
result[j]=p->data;++j;
p = root;
}
}
result[j] = '\0';
return result;
}
#include "HuffmanTree.h"
#include
int main(void){
char s[500];
READ:
printf("请输入一段话:");
gets(s);
int i=0,w[1000]={0},*word; char *c;
while(s[i]!='\0'){
w[s[i]+500]++;
++i;
}
int j=0; word = (int*)malloc(sizeof(int));
c = (char*)malloc(sizeof(char));
for(i=-500;i<500;++i){
if(w[i+500]!=0){
word = (int*)realloc(word,(j+1)*sizeof(int));
c = (char*)realloc(c,(j+1)*sizeof(char));
word[j] = w[i+500];
c[j] = i;
++j;
}
}
const int len = j;
if(len==1){
printf("请输入大于1种字符!\n");
goto READ;
}
HuffmanCode HC;HuffmanTree HT;
HuffmanCoding(HT,HC,word,c,len);
PrintHuffmanCode(HC,word,c,len);
i=0;
printf("赫夫曼编码后结果为:");
char code[1000]={'\0'};
while(s[i]!='\0'){
strcat(code,EnCode(HC,c,s[i],len));
++i;
}
printf("%s\n",code);
printf("解码结果为:%s",DeCode(code,HT));
printf("\n");
getchar();
return 0;
}
运行截图:
![赫夫曼树编码解码实例(C)_第1张图片](http://img.e-com-net.com/image/info8/2418730c00f4485db2c089454ee55361.png)
![赫夫曼树编码解码实例(C)_第2张图片](http://img.e-com-net.com/image/info8/742fa7e81c1545f2b86bf0e349fa861b.png)
![赫夫曼树编码解码实例(C)_第3张图片](http://img.e-com-net.com/image/info8/07165d72d3ee43a1b32d5bf49007f1c3.png)