此程序是利用C++语言编写的,在data.txt中有n个字符,通过程序可以统计data.txt中字符的总数以及每一个字符出现的频率。将data.txt中的字符编码并保存到encode.txt中,对encod.txt解码并将结果保存到decode.txt中。
代码:
#include"stdio.h"
#include"string.h"
#include"stdlib.h"
#define N 2000
//结点结构体
typedef struct{
double weight;//结点权值
unsigned int parent,lchild,rchild;
unsigned char ch;//结点值
}HTNode,*HuffmanTree;
typedef char **HuffmanCode;//动态分配数组存储哈弗曼编码表
typedef struct{//字符结构体
unsigned char ch;//字符值
unsigned int num;//字符个数
double frequent;//字符频率
}list;
HuffmanTree HT;//全局变量
list l[N];//全局变量
HuffmanCode HC; //全局变量
// //在HT[1...end]选择weigt最小的两个结点,其序号分别为s1和s2.
void Select(HuffmanTree HT,int end,int &s1,int &s2){
double min=1.0;
for(int i=1;i<=end;i++){
if(HT[i].parent==0&&HT[i].weight0),构造哈弗曼树HT,str存放n个字符
int i,m,s1,s2;
if(n<=1)
return;
m=2*n-1;
HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));//0号单元未用
for(i=1;i<=n;++i){
HT[i].ch=l[i].ch;
HT[i].weight =l[i].frequent;
HT[i].parent =0;
HT[i].lchild =0;
HT[i].rchild =0;
}
for(;i<=m;++i){
HT[i].parent =0;
HT[i].lchild =0;
HT[i].rchild =0;
}
for(i=n+1;i<=m;++i){
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 ;
}
}
//编码
void Encode(int n){
FILE *fp,*fw;
char code;
if((fp=fopen("data.txt","r"))==NULL)
printf("data.txt文件打开失败!");
if((fw=fopen("encode.txt","w+"))==NULL)
printf("encode.txt文件打开失败!");
char *cd;//存放一个Huffman编码的临时空间
int start;//Huffman编码在临时空间cd中的起始下标
unsigned int c,f;//c,f互为父子节点
HC=(HuffmanCode)malloc((n+1)*sizeof(char *));
cd=(char*)malloc(n*sizeof(char));//为临时空间分配存储空间(n个叶结点形成的HUffamnTree深度一定不会超过n)
cd[n-1]='\0';//设置字符串结束标记
for(int 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
}
free(cd);
fscanf(fp,"%c",&code);//从文件中读入第一个字符
while(!feof(fp)){
for(int i=1;i<=n;i++)
if(HT[i].ch==code)
break;
for(int r=0;HC[i][r]!='\0';r++)
fputc(HC[i][r],fw);
fscanf(fp,"%c",&code);
}
fclose(fw);
fclose(fp);
printf("编码成功,并存入encode.txt中");
}
//解码
void Decode(int n){
FILE *fp,*fw;
char code;
int i,j;
if((fp=fopen("encode.txt","r"))==NULL)
printf("encode.txt文件打开失败!");
if((fw=fopen("decode.txt","w+"))==NULL)
printf("decode.txt文件打开失败!");
i=j=2*n-1;//从根结点向下搜索
fscanf(fp,"%c",&code);
while(!feof(fp)){
if(code=='0')
i=HT[i].lchild ;//走向左孩子
else
i=HT[i].rchild ;//走向右孩子
if(HT[i].lchild ==0&&HT[i].rchild ==0)//HT[i]是叶结点
{
fputc(HT[i].ch,fw);
i=j;//回到根结点
}
fscanf(fp,"%c",&code);//读入下一个字符
}
printf("解码成功,并存入decode.txt中\n");
fclose(fp);
fclose(fw);
}
void Compare(int n){
FILE *fp,*fw;
char str1[N],str2[N];
int i=1;
if((fp=fopen("data.txt","r"))==NULL)
printf("data.txt文件打开失败!");
if((fw=fopen("decode.txt","r"))==NULL)
printf("decode.txt文件打开失败!");
fscanf(fp,"%c",&str1);
fscanf(fw,"%c",&str2);
while(i
相关文件截图:
程序运行结果截图: