#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef char *String;
static String thr[256];
typedef struct{
char ch;
long weight,parent,lchild,rchild;
}HTNode;
typedef struct{
HTNode data[512];
int root;
}HTree;
HTree T;
long charNum[256];
int oneChar=0,emptyFile=0;
char fileName[1000];
void getCharNum(FILE *&fp)
{
fseek(fp,0L,SEEK_SET);
fseek(fp,0L,SEEK_CUR);
char ch;
while(1){
fread(&ch,1,1,fp);
if(feof(fp))break;
charNum[ch]++;
}
}
int getSmallestWeight(int &a,int &b){
int i;
a=b=0;
for(i=1;i<512&&T.data[i].weight;i++)
if(T.data[i].parent==0)
{
a=i;
break;
}
for(i++;i<512&&T.data[i].weight;i++)
if(T.data[i].parent==0)
{
b=i;
break;
}
if(b==0){
T.root=a;
return 0;
}
for(i++;i<512&&T.data[i].weight;i++){
if(T.data[i].parent==0&&T.data[i].weight<T.data[a].weight)a=i;
else if(T.data[i].parent==0&&T.data[i].weight<T.data[b].weight)b=i;
}
return i;
}
void createHTree(){
int j=1,a,b,pos,nnum=0;
for(int i=0;i<=255;i++){
if(charNum[i]==0)continue;
nnum++;
T.data[j].rchild=T.data[j].lchild=T.data[j].parent=0;
T.data[j].weight=charNum[i];
T.data[j++].ch=i;
}
if(nnum==0) { emptyFile=1; return;}
else if(nnum==1){ oneChar=1; return;}
while(pos=getSmallestWeight(a,b)){
T.data[pos].lchild=a;
T.data[pos].rchild=b;
T.data[pos].parent=0;
T.data[pos].weight=T.data[a].weight+T.data[b].weight;
T.data[a].parent=T.data[b].parent=pos;
}
}
void createHuffmanCode(){
if(emptyFile==1||oneChar==1)return;
for(int i=1;!T.data[i].lchild;i++){
int j=i,p=0;
char temp[300]={0};
while(T.data[j].parent){
temp[p++]=(T.data[T.data[j].parent].rchild==j)+'0';
j=T.data[j].parent;
}
thr[T.data[i].ch]=(String) malloc(sizeof(char)*(p+1));
strcpy(thr[T.data[i].ch],strrev(temp));
}
}
int writeCompFile(FILE *&fp1){
char chh;
int a=1;
FILE *fp3=fopen(fileName,"r");
FILE *fp2=fopen("压缩后文件.txt","w");
while ((chh=fgetc(fp3))!=EOF)
{
fputs(thr[chh],fp2);
}
fclose(fp3);
fclose(fp2);
printf("下面是编码表:\n");
while(T.data[a].ch)
{
printf("%c %s\n",T.data[a].ch,thr[T.data[a].ch]);
a++;
}
return 0;
}
void comp(FILE *&fp1){
printf("请耐心等待...\n");
getCharNum(fp1);
createHTree();
createHuffmanCode();
writeCompFile(fp1);
printf("压缩完成,压缩后文件已保存至vc++6.0对应文件中\n");
}
int main ()
{
printf("下面输入文件路径(拖放入.txt文件即可,注意文件中不能含有中文字符)\n");
gets(fileName);
FILE *fp1=fopen(fileName,"r");
printf("开始压缩\n");
comp(fp1);
fclose(fp1);
return 0;
}