本代码主要解决从指定文件中统计每个字符的权重并构建huffman树
#include "stdafx.h"
#include "stdio.h"#include "string.h"
#include"stdlib.h"
typedef struct {
int weight;//权重
int parent;//父节点
int lchild;//左孩子
int rchild;//右孩子
}HTNode,*HuffmanTree;
typedef char **HuffmanCode;
typedef struct{
char data;
int weight;
}Node; //用来存储每个字符的权重
void HuffmanCoding(HuffmanTree &HT,HuffmanCode &HC,int *wet,int n)//构造赫夫曼树并求每一个字符的赫夫曼编码
{
void select_minium(HuffmanTree HT,int k,int &min1,int &min2) ;
int c,f;
if(n<=1)return;
int m=2*n-1;
HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));
for (int i=0;i<n;i++)
{
HT[i].parent = 0;
HT[i].lchild = 0;
HT[i].rchild = 0;
HT[i].weight = *wet; //wet为一个数组
wet++;
}
for(;i<m;i++)
{
HT[i].parent = 0;
HT[i].lchild = 0;
HT[i].rchild = 0;
HT[i].weight = 0;
}
int min1,min2;
for (i=n;i<m;i++)
{
select_minium(HT,i,min1,min2);
HT[min1].parent=i;HT[min2].parent=i;
HT[i].lchild=min1;HT[i].rchild=min2;
HT[i].weight=HT[min1].weight+HT[min2].weight;
}
HC=(HuffmanCode)malloc((n+1)*sizeof(char*));//分配n个字符编码的头指针
char *code=(char *)malloc(n*sizeof(char)); //求编码的工作空间
if(!code)
{
printf("code malloc faild!");
exit(-1);
}
code[n-1] = '\0'; //编码结束符,亦是字符数组的结束标志
for (i=0;i<n;i++)
{
int start=n-1;
for (c=i,f=HT[i].parent;f!=0;c=f,f=HT[f].parent)
{
if(HT[f].lchild==c) code[--start]='0';
else code[--start]='1';
}
HC[i]=(char*)malloc((n-start)*sizeof(char));
strcpy(HC[i],&code[start]);
}
free(code);
}
void select_minium(HuffmanTree HT,int k,int &min1,int &min2) //找最小的两个节点
{
int min(HuffmanTree HT,int n);
min1 = min(HT,k);
min2 = min(HT,k);
}
int min(HuffmanTree HT,int n)
{
int i = 0;
int min; //用来存放weight最小且parent为0的元素的序号
int min_weight; //用来存放weight最小且parent为0的元素的weight值
while(HT[i].parent != 0)
i++;
min_weight = HT[i].weight;
min = i;
//选出weight最小且parent为-1的元素,并将其序号赋给min
for(;i<n;i++)
{
if(HT[i].weight<min_weight && HT[i].parent==0)
{
min_weight = HT[i].weight;
min = i;
}
}
//选出weight最小的元素后,将其parent置1,使得下一次比较时将其排除在外。
HT[min].parent = 1;
return min;
}
int main(int argc, char* argv[])
{
void HuffmanCoding(HuffmanTree &HT,HuffmanCode &HC,int *wet,int n);
int i=0,n=0,j=0,m=0,temp=0;
char ch;
char All[438];
int wet[100]={0};
char *a=new char[100];
FILE *fp1,*fp2,*fp3,*fp4,*fp5;
if((fp1=fopen("message.txt","r"))==NULL)
{
printf("can not find the file\n");
exit(0);
}
if((fp2=fopen("fequency.txt","w"))==NULL)
{
printf("can not find the file\n");
exit(0);
}
if((fp3=fopen("codes.txt","w"))==NULL)
{
printf("can not find the file\n");
exit(0);
}
if((fp4=fopen("Mymessage.txt","r+"))==NULL)
{
printf("can not find the file\n");
exit(0);
}
if((fp5=fopen("huffmancoding.txt","r+"))==NULL)
{
printf("can not find the file\n");
exit(0);
}
ch=fgetc(fp1);
*a=ch;
wet[0]++;
n++;
while(!feof(fp1))
{
ch=fgetc(fp1);
for(int i=0;i<n;i++)
{
if(ch==*(a+i)){wet[i]++;break;}
else if(i==n-1){n++;*(a+n-1)=ch;wet[n-1]=1;break;}
}
}
for(i=0;i<n;i++)
{
fprintf(fp2,"%c %d\n",*(a+i),wet[i]);
printf("%c %d\n",*(a+i),wet[i]);
}
HuffmanTree HT;HuffmanCode HC;
HuffmanCoding(HT,HC,wet,n);
for (i=0;i<n;i++)
{
printf("%c的编码 ",*(a+i));
fprintf(fp3,"%c的赫夫曼编码",*(a+i));
printf("%s\n",HC[i]);
fprintf(fp3,"%s\n",HC[i]);
}
fclose(fp1);
fp1=fopen("message.txt","r");
while(!feof(fp1))//huffman译码过程
{
ch=fgetc(fp1);
for( i=0;i<n;i++)
{
if(*(a+i)==ch)
fprintf(fp5,"%s",HC[i]);
}
}
fclose(fp5);
if((fp5=fopen("huffmancoding.txt","r+"))==NULL)
{
printf("can not find the file\n");
exit(0);
}
int v=2*n-2;
while(!feof(fp5))
{
ch=fgetc(fp5);
if(ch=='0')
{
v=HT[v].lchild;
}
else if(ch=='1')
{
v=HT[v].rchild;
}
if (HT[v].lchild==0&&HT[v].rchild==0)
{
fprintf(fp4,"%c",*(a+v));
v=2*n-2;
}
}
fclose(fp1);
fclose(fp2);
fclose(fp3);
fclose(fp4);
return 0;
}