哈夫曼编解码器

此程序是利用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

相关文件截图:

哈夫曼编解码器_第1张图片

程序运行结果截图:

哈夫曼编解码器_第2张图片 

哈夫曼编解码器_第3张图片

你可能感兴趣的:(哈夫曼编解码器)