# include & ltstdio.h & gt
Typedef structlnode {/* -鏈表/
int數據;
struct LNode * next
}LNode,* Linklist
Typedef結構字符{/* -字符結構/
char數據;/* -字符值*
int頻率;/* -字符的頻率。
}性格;
typedef struct node {/*-Huffman contact/
char數據;/* -聯系方式*/
無符號整數權重;/* -重量/
無符號int parent、lchild、rchild
}HTNode,* HuffmanTree
鏈表L;/* -鏈表頭聯系人。
人物T[256];/*-存儲信息中出現的字符(不包括中文字符)-*/
赫芬頓樹HT;/* -存儲霍夫曼聯系方式。
char *HC[257],* HA[256];/*-Huffman碼緊密存儲在HC中,字符的碼按照字符值的位置存儲在HA中,比如A存儲在HA中的第65元-*/
int len = 0;/* -信息中出現的字符數/
int s1,S2;
int i,j;
char ch
char Infile[10],Outfile[10],decfile[10];/*-源信息文件,加密二進制文件(解密源文件),解密文件-*/
FILE *fp,*fin,* fout
Void Create_L(int n) /* -構建n個聯系人的前導聯系人鏈表(頭部插入法)。
{
int I;
鏈表p,k;
l =(Linklist)malloc(sizeof(LNode));
k = L;
for(I = 1;我& lt= n;i++)
{
p =(Linklist)malloc(sizeof(LNode));
p->;next = NULL
p->;數據= I;
k-& gt;next = p;k = p;
}
}
Void Init() /* -初始化,統計Infile,len中的字符個數以及每個字符的出現頻率- */
{/*-將這些len字符存儲在T[0]到T[len-1]中,然後根據頻率值將這些len字符按升序排列-*/
void QuickSort(Character A[],int p,int r);
printf("輸入Infilename:\ n ");
scanf("%s ",Infile);
if((fp=fopen(Infile," r))= = NULL)
{
printf("無法打開Infile!\ n ");
退出(0);
}
for(I = 0;我& lt256;i++)
{
T[i]。數據= I;
T[i]。頻率= 0;
}
而(!feof(fp))
{
ch = fgetc(FP);
T[ch]。頻率++;
}
for(i=0,j = 0;我& lt256;i++)
{
而(!T[i]。頻率和頻率。& amp我& lt256)
T[i++]。數據= 0;
如果(我& lt256)
T[j++]= T[I];
}
len = j;
create _ L(len);
QuickSort(T,0,len-1);
fclose(FP);
}
Void quicksort (character a [],int p,int r)/* - bubble方法按頻率升序排列數組A的元素。
{
人物t;
for(I = p;我& ltr;i++)
for(j = p;j & ltr-I;j++)
if(A[j]。頻率& gtA[j+1]。頻率)
{
t = A[j];A[j]= A[j+1];a[j+1]= t;
}
}
Voidselect ()/* -取出鏈表中權重最小的前兩個元素,按照升序在鏈表中插入新元素。
{
鏈表p,q;
int w,t;
p = L-& gt;接下來;
s 1 = p-& gt;數據;
q = p->;接下來;
S2 = q-& gt;數據;
w=HT[s1]。重量+HT[s2]。重量;
q->;數據= I;
l-& gt;next = q;
免費(p);
while(q->;下壹個)
{
如果(w & gtHT[q->;下壹個-& gt;數據】。重量)
{ t = q-& gt;數據;q->;data = q-& gt;下壹個-& gt;數據;q->;下壹個-& gt;數據= t;}
q = q-& gt;接下來;
}
}
Void Huffman編碼(int n)/*-N個字符被編碼並存儲在*HA[257]-*/
{
int m,c,f,start
int lencd
赫芬頓樹p;
char * cd
如果(n & lt=1)返回;
m = 2 * n-1;
HT =(HuffmanTree)malloc((m+1)* sizeof(HT node));
for(p=HT+1,I = 1;我& lt= n;++i,++p)
{
p->;data=T[i-1]。數據;
p->;重量=T[i-1]。頻率;
p->;parent = 0;
p->;l child = 0;
p->;rchild = 0;
}
for(;我& lt= m;++i,++p)
{
p->;數據= 0;
p->;權重= 0;
p->;parent = 0;
p->;l child = 0;
p->;rchild = 0;
}
for(I = n+1;我& lt= m;++i)
{
select();
HT[s1]。parent = I;
HT[s2]。parent = I;
HT[i]。l child = s 1;
HT[i]。rchild = s2
HT[i]。重量=HT[s1]。重量+HT[s2]。重量;
}
CD =(char *)malloc(n * sizeof(char));
for(start = 0;開始& ltn;start++)CD[I]= ' \ 0 ';
for(I = 1;我& lt= n;++i)
{
start = 0;
for(c=i,f=HT[i])。父母;f!=0;f=HT[f]。parent,c=HT[c]。父母)
{
if(HT[f]。lchild==c)
CD[start++]= ' 0 ';
其他
CD[start++]= ' 1 ';
}
lencd = start
HC[I]=(char *)malloc((lencd+1)* sizeof(char));
ch=HT[i]。數據;
HA[ch]=(char *)malloc((lencd+1)* sizeof(char));
for(start=lencd-1,j = 0;開始& gt=0;開始-)
{
HC[I][j]= CD[start];
j++;
}
HC[I][j]= ' \ 0 ';
strcpy(HA[ch],HC[I]);
}
免費(光盤);
}
vodieencryption()/*-根據HA中的編碼將Infile文件中的每個字符翻譯成二進制文件,並保存在outfile文件中-*/
{
printf("輸入輸出文件名:\ n ");
scanf("%s ",Outfile);
if((fout=fopen(Outfile," a"))==NULL)
{
printf("無法打開outfile!\ n ");
退出(0);
}
if((fin=fopen(Infile," r))= = NULL)
{
printf("無法在加密中打開Infile!\ n ");
退出(0);
}
而(!feof(fin))
{
ch = fgetc(fin);
fputs(HA[ch],fout);
}
fclose(fin);
fclose(fout);
}
Void decryption ()/* -對outfile文件中存儲的密文進行解碼,根據0,1從Huffman樹的根接點中選擇左右子樹。
直到葉片接觸,輸出葉片接觸值-*/
{
int m = 2 * len-1;
if((fin=fopen(Outfile," r))= = NULL)
{
printf("無法打開源文件!\ n ");
退出(0);
}
printf("輸入decfile!\ n ");
scanf("%s ",decfile);
if((fout=fopen(decfile," a))= = NULL)
{
printf("無法打開decfile!\ n ");
退出(0);
}
而(!feof(fin))
{
I = m;
while(HT[i]。兒童與健康。& ampHT[i]。rchild)
{
ch = fgetc(fin);
if(ch=='0') i=HT[i]。lchild
else if(ch=='1') i=HT[i]。rchild
其他
{
printf("END!\ n ");
退出(0);
}
}
printf("%c ",HT[i]。數據);
fprintf(fout," %c ",HT[i]。數據);
}
fclose(fin);
fclose(fout);
}
/* -主函數*/
void main()
{
void Init();/* -聲明的壹部分。
void Huffman coding(int n);
void Encrytion();
void解密();
init();/* -初始化函數*/
Huffman coding(len);/* -編碼功能*
encryption();/* -加密功能*/
解密();/* -解密函數*
}