Huffman编码

Huffman编码

main.h
#ifndef main_h
#define main_h

typedef struct HTNode
{
	int weight;
	int lchild,rchild,parent;
}HTNode;

typedef struct HCNode
{
	char ch;
	char bits[27];
	int len;
}HCNode;

#endif


#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"main.h"

int ScanString(char str[],char s[],int ct[])
{
	int num=0,i;
	int temp[27];
	for(i=1;i<27;i++)
		temp[i]=0;
	for(i=0;str[i];i++)
		if(str[i]>='a'&&str[i]<='z')
			temp[str[i]-'a'+1]++;
	for(i=1;i<27;i++)
		if(temp[i])
		{
			num++;
			s[num]='a'+i-1;
			ct[num]=temp[i];
		}
	return num;
}

void Select(HTNode *HT,int k,int *s1,int *s2)
{
	int m1=32767,m2=32767;
	int i;
	for(i=1;i<=k;i++)
	{
		if(HT[i].weight<m1&&HT[i].parent==0)
		{
			m1=HT[i].weight;
			*s1=i;
		}
	}
	for(i=1;i<=k;i++)
	{
		if(HT[i].weight<m2&&HT[i].parent==0&&*s1!=i)
		{
			m2=HT[i].weight;
			*s2=i;
		}
	}
}
			
void CHuffTree(HTNode *HT,char s[],int ct[],int num)
{
	int i,s1,s2;
	for(i=1;i<num*2;i++)
		HT[i].lchild=HT[i].rchild=HT[i].parent=HT[i].weight=0;
	for(i=1;i<=num;i++)
		HT[i].weight=ct[i];
	for(i=num+1;i<2*num;i++)
	{
		Select(HT,i-1,&s1,&s2);
		HT[s1].parent=i;
		HT[s2].parent=i;
		HT[i].lchild=s1;
		HT[i].lchild=s2;
		HT[i].weight=HT[s1].weight+HT[s2].weight;
	}
}

void GetCode(HTNode *HT,HCNode *HC,char s[],int num)
{
	char cd[27];
	int start;
	int p,c,i;
	cd[27]='\0';
	for(i=1;i<=num;i++)
		HC[i].ch=s[i];
	for(i=1;i<=num;i++)
	{
		start=27;
		c=i;
		while((p=HT[c].parent)>0)
		{
			if(HT[p].lchild==c)
				cd[--start]='0';
			else
				cd[--start]='1';
			c=p;
		}
		strcpy(HC[i].bits,&cd[start]);
		HC[i].len=27-start;
	}
}

void Coding(HCNode *HC,char str[],int num)
{
	int i,j;
	FILE *fp;
	fp=fopen("codefile.dat","w");
	if(fp==NULL)
	{
		printf("Can not open the file!\n");
		return ;
	}
	while(*str)
	{
		for(i=1;i<=num;i++)
		{
			if(*str==HC[i].ch)
			{
				for(j=0;j<HC[i].len;j++)
					fprintf(fp,"%c",HC[i].bits[j]);
				break;
			}
		}
		str++;
	}
	fclose(fp);
}

void Decoding(HCNode *HC,char code[],int num)
{
	int flag,i,j,k=0;
	char cd[27];
	FILE *fp;
	fp=fopen("codefile.dat","r");
	if(fp==NULL)
	{
		printf("Can not open the file!\n");
		return ;
	}
	while(!feof(fp))
	{
		flag=0;
		for(i=0;i<=num&&flag==0&&!feof(fp);i++)
		{
			cd[i]=' ';
			cd[i+1]='\0';
			fscanf(fp,"%c",&cd[i]);
			for(j=1;j<=num;j++)
			{
				if(strcmp(cd,HC[j].bits)==0)
				{
					code[k++]=HC[j].ch;
					flag=1;
					break;
				}
			}
		}
	}
	code[k]='\0';
	fclose(fp);
}

int main(int argc,char *argv[])
{
	HTNode *HT;
	HCNode *HC;
	FILE *fp;
	int num,i,k=0;
	int ct[27];
	char s[27];
	char str[200],code[200];
	char m[200];
	printf("Please input:\n");
	scanf("%s",str);
	num=ScanString(str,s,ct);
	HT=(HTNode *)malloc(sizeof(HTNode)*num*2);
	HC=(HCNode *)malloc(sizeof(HCNode)*(num+1));
	CHuffTree(HT,s,ct,num);
	GetCode(HT,HC,s,num);
	Coding(HC,str,num);

	Decoding(HC,code,num);
	printf("Code:\n");
	for(i=1;i<=num;i++)
		printf("%c: %s\n",HC[i].ch,HC[i].bits);
	fp=fopen("codefile.dat","r");
	if(fp==NULL)
	{
		printf("Can not open the file!\n");
		exit(-1);
	}
	printf("After coding:\n");
    while(!feof(fp))
	{
		fscanf(fp,"%c",&m[k]);
		k++;
	}
	m[k-1]='\0';
	printf("%s\n",m);
	printf("Decoding:\n");
	printf("%s\n",code);
	return 0;
}



你可能感兴趣的:(数据结构,C语言,Huffman)