#定義霍夫曼樹h
#endif
# include & ltstdio.h & gt
typedef結構{
無符號整數權重;
unsigned int parent、lchild、rchild
}HTNode、* HuffmanTree//存儲赫夫曼樹的節點類型。
typedef char * * HuffmanCode//用於存儲字符集中每個字符對應的霍夫曼碼。
void strcpy(char * S1,char * S2){//將字符串S2復制到s 1。
int I = 0;
(S2【我】!= '\0' ){
s 1【I】= S2【I】;
i++;
}
s 1【I】=‘\ 0‘;
}
void Select(哈夫曼特裏HT,int t,int & amps1,int & ampS2){//從HT【1】到HT【t-1】,找出兩個最小權重的S1和S2。
int I = 1;
s 1 = S2 = 0;
HT【0】。權重= 65535;
while(我& lt= t){//遍歷查找權重最小的節點S1。
if(HT【I】。parent == 0。& ampHT【I】。重量& ltHT【s 1】。重量)
s 1 = I;
i++;
}
I = 1;
while(我& lt= t){//遍歷查找除S1之外權重最小的節點S2。
如果(我!= s1。& ampHT【I】。parent == 0。& ampHT【I】。重量& ltHT【S2】。重量)
S2 = I;
i++;
}
}
國際赫夫曼編碼公司赫夫曼代碼和。HC,int *w,int n){//根據每個字符的權重構造Hoeffmann樹HT,對應的霍夫曼碼存儲在HC中。
int s1,s2,m,I,start
無符號整數c,f;
ht node * p;
char * cd
if(n & lt;= 1)返回0;
m = 2 * n-1;//赫夫曼樹的總結點樹是m。
HT =(HuffmanTree)malloc((m+1)* sizeof(HT node));//申請存儲霍夫曼樹的空間。
for(p = HT+1,I = 1;我& lt= n;++i,++p,++ w){//將每個葉節點的權重分配給相應的權重,並將parent、lchild和rchild分配為0。
p-》;weight = *(w+1);
p-》;parent = p-& gt;l child = p-& gt;rchild = 0;
}
for(;我& lt= m;++i,++ p){//將每個非葉節點的weight、parent、lchild和rchild賦值為0。
p-》;權重= p-》;parent = p-& gt;l child = p-& gt;rchild = 0;
}
for(I = n+1;我& lt= m;++ I){//構造壹棵Hoeffmann樹並為每個非葉節點賦值。
select(HT,i - 1,s1,S2);
HT【s 1】。parent = I;HT【S2】。parent = I;
HT【I】。lchild = s 1;HT【I】。rchild = s2
HT【I】。權重= HT【s 1】。重量+HT【S2】。重量;
}
HC =(HuffmanCode)malloc((n+1)* sizeof(char *));//應用空間,用於存儲指向字符數組的指針,該數組存儲每個字符對應的霍夫曼碼。
CD =(char *)malloc(n * sizeof(char));//申請霍夫曼編碼。
CD【n-1】=‘\ 0‘;//編碼終止符
for(I = 1;我& lt= n;++ I){//逐字符查找霍夫曼編碼。
start = n-1;//在數組cd【】的前面位置編碼
for(c = I,f = HT【I】。父母;f!= 0;C = f,f = HT【f】。parent)//從葉到根的反向編碼。
if(HT【f】。lchild == c)
CD【-start】=‘0‘;
其他
CD【-start】=‘1‘;
HC【I】=(char *)malloc((n-start)* sizeof(char));//為第I個字符編碼分配空間。
strcpy(HC【I】,& ampCD【start】);//將cd【】數組的起始位置復制到n-1位置到HC【I】
}
免費(光盤);//釋放空間
返回1;
}
以上是第壹部分
# include & ltstdio.h & gt
# include & ltstdlib.h & gt
#包含“Huffman_Tree.h“
#define Yes 1 //當程序已經調用初始化Hoeffmann樹的InitHuff_T()函數,或者已經從htfTree文件中讀取該函數時,請將Init_Mode設置為Yes,否則為NO。
#定義0號
void init huff _ T(Huffman tree & amp;赫夫曼代碼和。HC,char ch【】,int & ampn){//初始化Hoeffmann數,要求用戶輸入字符和相應的權重。
int i = 1,w【100】,tem,j;
char a【20】;
文件*保存;
Printf(“請輸入編碼字符集n的大小:“);
scanf(“% d“,& ampn);//獲取用戶輸入的字符集的數量。
while(我& lt= n){//獲取用戶輸入的字符和對應的權重,分別存儲在ch【】和w【】數組中。
Printf(“請輸入%d字符及其權重w:“,I);
fflush(stdin);
scanf(“% c % d“,& ampch【I】;w【I】);
i++;
}
ch【I】=‘\ 0‘;
哈夫曼編碼(HT、HC、w、n);//根據用戶的輸入,生成每個字符對應的赫夫曼數和霍夫曼碼,並分別存儲在HT樹和HC中。
if((save = fopen(“htftree“,“w“))= = null){//打開用於存儲赫夫曼樹的文件。
printf(“打開文件失敗......\ n ");
退出(0);
}
tem = n;//14的下壹行是將字符集的大小轉換為字符形式並寫入文件。
j = 0;
while(tem!= 0 ){
tem = tem/10;
j++;
}
tem = n;
a【j】=‘\ 0‘;
while(tem!= 0 ){
a【j-1】=(char)(tem % 10+48);
tem = tem/10;
j-;
}
fputs(a,save);
printf(“% d \ n“,n);//將字符集大小n輸出到屏幕
fputc(“\ n“,save);
for(I = 1;我& lt= n;i++){//將每個字符和對應的霍夫曼代碼分別輸出到文件和屏幕。
fputc(ch【I】,save);printf(“% c \ t“,ch【I】);
fputc(‘t‘,save);
fputs(HC【I】,save);printf(“% s \ n“,HC【I】);
fputc(“\ n“,save);
}
for(I = 1;我& lt= 2 * n-1;i++){//將Hoeffmann樹的每個節點的parent、lchild和rchild分別寫入文件。
tem = HT【I】。父母;//將I節點的父節點轉換為字符並寫入文件。
if(tem = = 0 ){
fputc(tem+48,保存);
fputc(‘,保存);
}
否則{
j = 0;
while(tem!= 0 ){
tem = tem/10;
j++;
}
tem = HT【I】。父母;
a【j】=‘\ 0‘;
while(tem!= 0 ){
a【j-1】=(char)(tem % 10+48);
tem = tem/10;
j-;
}
fputs(a,save);
fputc(‘,保存);
}
tem = HT【I】。lchild//將I節點的lchild轉換為字符並寫入文件。
if(tem = = 0 ){
fputc(tem+48,保存);
fputc(‘,保存);
}
否則{
j = 0;
while(tem!= 0 ){
tem = tem/10;
j++;
}
tem = HT【I】。lchild
a【j】=‘\ 0‘;
while(tem!= 0 ){
a【j-1】=(char)(tem % 10+48);
tem = tem/10;
j-;
}
fputs(a,save);
fputc(‘,保存);
}
tem = HT【I】。rchild//將I節點的rchild轉換為字符並寫入文件。
if(tem = = 0 ){
fputc(tem+48,保存);
fputc(“\ n“,save);
}
否則{
j = 0;
while(tem!= 0 ){
tem = tem/10;
j++;
}
tem = HT【I】。rchild
a【j】=‘\ 0‘;
while(tem!= 0 ){
a【j-1】=(char)(tem % 10+48);
tem = tem/10;
j-;
}
fputs(a,save);
fputc(“\ n“,save);
}
}
fclose(保存);
}
void編碼(HuffmanTree & amp赫夫曼代碼和。HC,char ch【】){//根據霍夫曼碼將用戶指定文件中的字符編碼成相應的代碼,並將得到的代碼存儲在用戶指定文件中。
FILE *ToBeTran,* CodeFile
char tobe tran _ Name【100】,CodeFile _ Name【100】;//存儲用戶指定的文件的文件名。
int I;
char c;
Printf(“請輸入要編碼的文件的文件名:“);
scanf(“% s“,tobe tran _ Name);//獲取要編碼的文件的文件名。
if((tobe tran = fopen(tobe tran _ name,“r“))= = null){//打開文件。
printf(“打開文件失敗......\ n ");
退出(0);
}
Printf(“請輸入存儲編碼信息的文件的文件名:“);
scanf(“% s“,代碼文件名稱);//獲取存儲編碼信息的文件的文件名。
if((codefile = fopen(codefile _ name,“w“))= = null){//打開文件。
printf(“打開文件失敗......\ n ");
退出(0);
}
c = fgetc(tobe tran);//從文件中讀取字符
而(c!= EOF){//對文件中的每個字符進行編碼,直到文件結束。
I = 1;
而(c!= ch【I】& amp;& ampch【I】!=‘\ 0‘‘//在ch【】數組中查找從文件中讀取的字符。
i++;
if(ch【I】=‘\ 0‘‘){//未找到,C不在ch【】數組中,C無法識別,程序錯誤,退出。
Printf(“字符%c無法識別,程序將退出。\n“,c);
退出(0);
}
fputs(HC【I】,CodeFile);//如果找到,將C對應的霍夫曼碼寫入文件。
printf(“% s“,HC【I】);//將C對應的霍夫曼碼輸出到屏幕上。
c = fgetc(tobe tran);//讀取文件中的下壹個字符。
}
printf(" \ n ");
fclose(托貝特蘭);
fclose(代碼文件);
}
void decoding(Huffman tree ht,Charch【】,int n){//對存儲霍夫曼編碼所表示的信息的指定文件進行解碼,將其轉換為相應的字符表示形式,並存儲在指定文件中。
int p,I = 1;
字符代碼【1000】,c;
char CodeFile _ Name【100】,text file _ Name【100】;//存儲用戶指定的文件的文件名。
p = 2 * n-1;
FILE *CodeFile,* TextFile
Printf(“請輸入要翻譯的文件名:“);
scanf(“% s“,代碼文件名稱);//獲取要翻譯的文件的文件名。
if((codefile = fopen(“codefile“,“r“))= = null){//打開文件。
printf(“打開文件失敗......\ n ");
退出(0);
}
Printf(“請輸入存儲翻譯字符的文件的文件名:“);
scanf(“% s“,TextFile _ Name);//獲取存儲翻譯字符的文件的文件名。
if((textfile = fopen(textfile _ name,“w“))= = null){//打開文件。
printf(“打開文件失敗......\ n ");
退出(0);
}
c = fgetc(代碼文件);
而(c!= EOF ){
代碼【I】= c;
i++;
c = fgetc(代碼文件);
}
代碼【I】=“\ 0“;//從文件中讀取字符並將其存儲在code【】數組中。
I = 1;
while(代碼【I】!=‘\ 0‘& amp;& ampp!= 0){//解碼數組代碼【】中的霍夫曼代碼。
if(代碼【I】= =‘0‘)
p = HT【p】。lchild//進入左分支
其他
p = HT【p】。rchild//輸入正確的分支
如果(!HT【p】。lchild & amp& amp!HT【p】。rchild){//輸入葉節點。
fputc(ch【p】,TextFile);//將相應的字符寫入文件。
printf(“% c“,ch【p】);//將相應的字符輸出到屏幕。
p = 2 * n-1;//從樹根重新解碼
}
i++;
}
printf(" \ n ");
}
void read huff _ T(Huffman tree & amp;赫夫曼代碼和。HC,char ch【】,int & ampn){//從文件中讀取赫夫曼樹。
FILE * htfTree
char c【100】,ch 1;
int i,j,t;
if((htftree = fopen(“htftree“,“r“))= = null){//打開包含Hoeffmann樹信息的文件。
printf(“打開文件失敗......\ n ");
退出(0);
}
fgets(c,10,htfTree);//獲取Hoeffmann中子葉節點數的字符串表示形式。
I = 0;//以下六行將字符串形式轉換為整數形式。
while(c【I】!=‘\ n‘‘
i++;
n = 0;
for(j = 0;j & lt我;j++)
n = 10 * n+c【j】--“0“;//找出葉節點的數量n
HC =(HuffmanCode)malloc((n+1)* sizeof(char *));//申請HC空間
HT =(Huffman tree)malloc((2 * n)* sizeof(HT node));//申請赫夫曼樹存儲空間。
I = 1;
while(我& lt= n ){
ch【I】= fgetc(htfTree);//讀取字符集中的字符。
HC【I】=(char *)malloc((10)* sizeof(char));//申請霍夫曼編碼空間,用於存儲讀取的字符集中的字符。
fgetc(htfTree);//輸出“\ t”
ch 1 = fgetc(htfTree);//讀取霍夫曼碼並存儲在對應的HC【I】【】數組中。
int j = 0;
while(ch 1!=‘\ n’){
HC【I】【j】= ch 1;
j++;
ch 1 = fgetc(htfTree);
}
HC【I】【j】=‘\ 0‘;
i++;
}
ch【I】=‘\ 0‘;
I = 0;
while(我& lt2 * n-1){//讀取Hoeffmann樹的每個節點的parent、lchild和rchild並將其分配給Hoeffmann樹HT。
ch 1 = fgetc(htfTree);//讀取parent的字符串形式,存儲在c【】中,並轉換為整數形式,賦值給HT【I】。parent。
j = 0;
while(ch 1!= ' ' ){
c【j】= ch 1;
j++;
ch 1 = fgetc(htfTree);
}
HT【I+1】。parent = 0;
for(t = 0;t & ltj;t++)
HT【I+1】。parent = 10 * HT【I+1】。parent+c【t】--“0”;
ch 1 = fgetc(htfTree);//讀取lchild的字符串形式,並將其轉換為整數形式,並將其賦給HT【I】。l child。
j = 0;
while(ch 1!= ' ' ){
c【j】= ch 1;
j++;
ch 1 = fgetc(htfTree);
}
HT【I+1】。l child = 0;
for(t = 0;t & ltj;t++)
HT【I+1】。lchild = 10 * HT【I+1】。l child+c【t】--“0“;
ch 1 = fgetc(htfTree);//讀取rchild的字符串形式並將其轉換為整數形式,並將其賦給HT【I】。rchild。
j = 0;
while(ch 1!=‘\ n’){
c【j】= ch 1;
j++;
ch 1 = fgetc(htfTree);
}
HT【I+1】。rchild = 0;
for(t = 0;t & ltj;t++)
HT【I+1】。rchild = 10 * HT【I+1】。rchild+c【t】--“0“;
i++;
}
}
int main(){
赫夫曼特裏HT;
HuffmanCode HC
char ch【100】;//用於存儲字符集。
int n,Init _ Mode = No//n是字符集的大小,Init_Mode = No表示內存中沒有Hoeffmann樹信息。
char模式;//讓用戶選擇不同的操作。
Printf(“請輸入您要選擇的函數\ n“);
printf(“\ t \ ti-初始化\ t \t\tE -編碼\ n“);
printf(“\ t \ TD-decoding \ t \ t \ tQ-退出程序\ n“);
scanf(“% c“,& amp模式);//獲取用戶選擇的操作
while(模式!=‘Q‘amp;& amp模式!=‘Q‘){//當用戶輸入不是Q或Q時,執行相應的操作。
開關(模式){
案例“I”:
init huff _ T(HT,HC,ch,n);
Init _ Mode = Yes
打破;
案例“I”:
init huff _ T(HT,HC,ch,n);
Init _ Mode = Yes
打破;
案例“E”:
if(No = =初始化模式)
read huff _ T(HT,HC,ch,n);
編碼(HT、HC、ch);
Init _ Mode = Yes
打破;
案例“e”:
if(No = =初始化模式)
read huff _ T(HT,HC,ch,n);
編碼(HT、HC、ch);
Init _ Mode = Yes
打破;
案例“D”:
if(No = =初始化模式)
read huff _ T(HT,HC,ch,n);
解碼(HT,ch,n);
Init _ Mode = Yes
打破;
案例“d”:
if(No = =初始化模式)
read huff _ T(HT,HC,ch,n);
解碼(HT,ch,n);
Init _ Mode = Yes
默認值:
Printf(“您的輸入有誤,請重新選擇。\ n ");
}
Printf(“請輸入您要選擇的函數\ n“);
printf(“\ ti-初始化\ te-編碼\ n“);
printf(“\ TD-decoding \ TQ-退出程序\ n“);
fflush(stdin);
scanf(“% c“,& amp模式);//讓用戶繼續選擇相應的操作,直到用戶選擇退出。
}
返回0;
}
第二部分
1。進入vc++6.0
2。創建壹個新項目並選擇Win32控制臺應用程序。
壹份空白的工程確認書
3。創建壹個名為Huffman_Tree.h的新c++源文件請記住命名非常重要,然後使用此名稱粘貼烘焙shell的第壹部分並編譯和保存。
4。創建壹個名為Hoeffmann的新c++源文件。cpp,然後復制粘貼第二部分,編譯並保存,然後就完成了,可以執行了。
需要註意的是,編譯後生成的可執行文件保存在新項目的默認文件夾中。當然,您也可以在新項目中選擇要保存可執行文件的文件夾,以便於搜索。