📄 huff.c
字号:
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <stdlib.h>
#define NULL 0
#define OK 1
#define ERROR 0
#define OVERFLOW -2
#define MAX_NUM 1000
#define MAX 100
typedef struct{
unsigned int weight;
unsigned int parent,lc,rc;
}HTNode,*HuffmanTree; /*动态分配数组存储Huffman树*/
typedef int Status;
typedef char **HuffmanCode; /*动态分配数组存储Huffman编码表*/
typedef struct Huffman{
HuffmanTree HT;
char *c;
int ln;
HuffmanCode HC;
}Huffman;
void Select(HuffmanTree HT,int end,int *s1,int *s2)
{
int i;
int min1=MAX_NUM;
int min2;
for (i=1;i<=end;i++)
{
if (HT[i].parent==0&&HT[i].weight<min1)
{
*s1=i;
min1=HT[i].weight;
}
}
min2=MAX_NUM;
for(i=1;i<=end;i++)
{
if(HT[i].parent==0&&(*s1!=i)&&min2>HT[i].weight)
{
*s2=i;
min2=HT[i].weight;
}
}
}
Huffman HuffmanCoding(Huffman Hfm)
{
int i,n,m,s1,s2,start;
int c,f;
char *cd;
n=Hfm.ln;
if(n<=1) return Hfm;
m=2*n-1;
for(i=n+1;i<=m;++i) /*建立Huffman树*/
{
Select(Hfm.HT,i-1,&s1,&s2);
Hfm.HT[s1].parent=i;
Hfm.HT[s2].parent=i;
Hfm.HT[i].lc=s1;
Hfm.HT[i].rc=s2;
Hfm.HT[i].weight=Hfm.HT[s1].weight+Hfm.HT[s2].weight;
}
Hfm.HC=(HuffmanCode)malloc((n+1)*sizeof(char *)); /*分配n个字符编码的头指针向量*/
cd=(char *)malloc(n*sizeof(char)); /*分配求编码的工作空间*/
cd[n-1]='\0'; /*编码结束符*/
for(i=1;i<=n;++i) /*逐个字符求Huffman编码*/
{
start=n-1; /*编码结束符位置*/
for(c=i,f=Hfm.HT[i].parent;f!=0;c=f,f=Hfm.HT[f].parent) /*从叶子到根逆向求编码*/
{
if(c==Hfm.HT[f].lc) cd[--start]='0';
else cd[--start]='1';
}
Hfm.HC[i]=(char *)malloc((n-start)*sizeof(char)); /*为第i个字符编码分配空间*/
strcpy(Hfm.HC[i],&cd[start]); /*从cd复制编码(串)到HC*/
}
free(cd);
return Hfm;
}
Huffman InitHuffman(Huffman Hfm)
{
int i,n;
clrscr();
printf("The chars and weights will be saved in the file \"hfmTree\"\n");
printf("Please input the number of the chars: ");
scanf("%d",&n);
Hfm.HT=(HuffmanTree)malloc((2*n)*sizeof(HTNode));
Hfm.c=(char *)malloc((n+1)*sizeof(char));
printf("Please input the char: ");
for(i=1;i<=n;i++)
scanf("%s",&Hfm.c[i]);
printf("Please input the weight of the char: ");
for(i=1;i<=n;i++)
scanf("%d",&Hfm.HT[i].weight);
for(i=1;i<=n;i++)
{
Hfm.HT[i].parent=0;
Hfm.HT[i].lc=0;
Hfm.HT[i].rc=0;
}
for(;i<=2*n-1;++i)
{
Hfm.HT[i].weight=0;
Hfm.HT[i].parent=0;
Hfm.HT[i].lc=0;
Hfm.HT[i].rc=0;
}
Hfm.ln=n;
return Hfm;
}
Huffman RebuildHuffman(Huffman Hfm)
{
int n,i;
FILE *fp;
fp=fopen("hfmTree","wt");
Hfm=InitHuffman(Hfm);
fprintf(fp,"%d\n",Hfm.ln);
for(i=1;i<=Hfm.ln;i++)
fprintf(fp,"%c %d",Hfm.c[i],Hfm.HT[i].weight);
rewind(fp);
fclose(fp);
Hfm=HuffmanCoding(Hfm);
return Hfm;
}
void Encoding(Huffman Hfm)
{
int i=0,j=0,n;
char ch[MAX];
FILE *fp,*ffp;
n=Hfm.ln;
printf("\n\n*******************Encoding************************\n\n");
if((ffp=fopen("ToBeTran","rt"))==NULL)
{
printf("\nPlease input the sentence: ");
scanf("%s",&ch);
printf("\n");
fp=fopen("CodeFile","wt+");
}
else
{
fscanf(ffp,"%s",ch);
fclose(ffp);
}
while(ch[j])
{
for(i=1;i<=n;i++)
if(ch[j]==Hfm.c[i])
{
printf("%s",Hfm.HC[i]);
fprintf(fp,"%s",Hfm.HC[i]);
break;
}
j++;
}
rewind(fp);
fclose(fp);
}
void Decoding(Huffman Hfm)
{
HuffmanTree p;
int i,n;
int j=0;
char d[50];
FILE *fp;
n=Hfm.ln;
printf("\n\n******************Decoding************************\n\n");
if((fp=fopen("CodeFile","rt"))==NULL)
{
printf("Please input the code:");
scanf("%s",&d);
}
else
{
fscanf(fp,"%s",d);
fclose(fp);
}
printf("\nThe file is : ");
fp=fopen("TextFile","wt+");
while(d[j])
{
p=&Hfm.HT[2*n-1];
while(p->lc||p->rc)
{
if(d[j]=='0')
{ i=p->lc; p=&Hfm.HT[i]; }
else
{ i=p->rc; p=&Hfm.HT[i]; }
j++;
}
printf("%c",Hfm.c[i]);
fprintf(fp,"%c",Hfm.c[i]);
}
fclose(fp);
}
Huffman InputHuffman(Huffman Hfm)
{
int n,i;
FILE *fp;
fp=fopen("hfmTree","rt");
if(fp==NULL)
{
Hfm=InitHuffman(Hfm);
fp=fopen("hfmTree","wt");
fprintf(fp,"%d\n",Hfm.ln);
for(i=1;i<=Hfm.ln;i++)
fprintf(fp,"%c%d",Hfm.c[i],Hfm.HT[i].weight);
rewind(fp);
}
else
{
fscanf(fp,"%d\n",&n);
Hfm.c=(char *)malloc((n+1)*sizeof(char));
Hfm.HT=(HuffmanTree)malloc((2*n)*sizeof(HTNode));
for(i=1;i<=n;i++)
fscanf(fp,"%c%d",&Hfm.c[i],&Hfm.HT[i].weight);
for(i=1;i<=n;i++)
{
Hfm.HT[i].parent=0;
Hfm.HT[i].lc=0;
Hfm.HT[i].rc=0;
}
for(;i<=2*n-1;++i)
{
Hfm.HT[i].weight=0;
Hfm.HT[i].parent=0;
Hfm.HT[i].lc=0;
Hfm.HT[i].rc=0;
}
Hfm.ln=n;
}
fclose(fp);
Hfm=HuffmanCoding(Hfm);
return Hfm;
}
void OutputHuffman(Huffman Hfm)
{
int i,n;
n=Hfm.ln;
printf("\n\n******************Output the code of the chars****************\n\n");
for(i=1;i<=n;i++)
{
printf("\n");
printf("Char: %c\t",Hfm.c[i]);
printf("Weight: %d\t",Hfm.HT[i].weight);
printf("Code: ");
puts(Hfm.HC[i]);
}
}
int main()
{
struct Huffman Hfm;
char choice;
Hfm=InputHuffman(Hfm);
while(choice!='q')
{
clrscr();
printf("\n\n\n*************************************\n\n");
printf("E. Code:\n\n");
printf("D. Translate:\n\n");
printf("P. Output bianma code :\n\n");
printf("R. rebuild Huffman tree:\n\n");
printf("Q. exit\n\n");
printf("\n************************************\n\n");
printf("Please enter your choice: ");
scanf("%c",&choice);
switch(choice)
{
case 'e':
case 'E':
clrscr();
Encoding(Hfm);
printf("\nPlease enter anykey to continue!\n");
getch(); break;
case 'd':
case 'D':
clrscr();
Decoding(Hfm);
printf("\nPlease enter anykey to continue!\n");
getch(); break;
case 'p':
case 'P':
clrscr();
OutputHuffman(Hfm);
printf("\nPlease enter anykey to continue!\n");
getch(); break;
case 'r':
case 'R':
clrscr();
Hfm=RebuildHuffman(Hfm);
printf("\nInitial!\n");
getch(); break;
case 'q':
case 'Q':
break;
default:
printf(" Your choice is wrong!\n Please enter anykey to choice again!\n");
getch(); break;
}
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -