#include<stdlib.h>#include<string.h>#include<stdio.h>#define MAX_Node_num 30typedef struct{char elem;unsigned int weight;unsigned int parent,lc,rc;}HTNode,*HuffmanTree;typedef char ** HuffmanCode;typedef struct weight{char elem;unsigned int m_weight;}Weight;int f,start,c,s1,s2;//橫向列印,將樹打橫放置。。。//*************列印哈夫曼樹函數****************int numb=0 ;void coprint(HuffmanTree start,HuffmanTree HT) //start=ht+26這是一個遞迴演算法{if(start!=HT){numb++; //number=0 該變數為已被聲明為全域變數coprint(HT+start->rc,HT); //遞迴先序遍曆printf("%*d\n",5*numb,start->weight);//if(start->rchild==0) cout<<info[start-HT-1]<<endl;printf("%d",start->weight) ;coprint(HT+start->lc,HT);numb--;}}void Tree_printing(HuffmanTree HT,int num){HuffmanTree p;p=HT+2*num-1; //p=HT+26printf("下面列印赫夫曼樹\n") ;coprint(p,HT); //p=HT+26printf("列印工作結束\n") ;}void Select(HuffmanTree HT,int i,int &s1,int &s2){ //在建立哈夫曼樹的所有結點中選擇權值最小的兩個結點存放在s1,s2中int j,k=1;while(HT[k].parent!=0)k++;s1=k;for(j=1;j<=i;++j)if(HT[j].parent==0&&HT[j].weight<HT[s1].weight)s1=j;k=1;while(HT[k].parent!=0||k==s1)k++;s2=k;for(j=1;j<=i;++j)if(HT[j].parent==0&&HT[j].weight<HT[s2].weight&&j!=s1)s2=j;}void HuffmanCoding(HuffmanTree &HT ,HuffmanCode &HC ,Weight *w ,int n){int m,i;m=2*n-1;if(m<=1) return ;HT = (HuffmanTree)malloc((m+1) * sizeof(HTNode));for (i=1; i<=n; i++){ //初始化HT[i].elem=w[i-1].elem;HT[i].weight=w[i-1].m_weight;HT[i].parent=0;HT[i].lc=0;HT[i].rc=0;}for (i=n+1; i<=m; i++){ //初始化HT[i].weight=0;HT[i].parent=0;HT[i].lc=0;HT[i].rc=0;}for(i=n+1;i<=m;++i)//建立哈夫曼樹過程{Select(HT,i-1,s1,s2);HT[s1].parent=i;HT[s2].parent=i;HT[i].lc=s1;HT[i].rc=s2;HT[i].weight=HT[s1].weight+HT[s2].weight;}printf(" i weight parent lc rc \n") ;for (i=1; i<=m; i++)printf("\n%4d%8d%8d%8d%8d",i,HT[i].weight,HT[i].parent,HT[i].lc, HT[i].rc);HC=(HuffmanCode)malloc((n+1)*sizeof(char*)) ;char *cd ;cd=(char*)malloc(n*sizeof(char)) ;cd[n-1]='\0';for(i=1;i<=n;++i){start=n-1;for(c=i,f=HT[i].parent ;f!=0;c=f,f=HT[f].parent)if(HT[f].lc==c)cd[--start]='0';else cd[--start]='1';HC[i]=(char*)malloc((n-start)*sizeof(char));strcpy(HC[i],&cd[start]);}free (cd);}void OutputHuffman(HuffmanTree HT,int n){char ch;printf("請輸入編碼\n");int j=2*n-1;getchar();ch=getchar();while(ch!='\n'){if(ch=='0'){j=HT[j].lc;}else if(ch=='1'){j=HT[j].rc;}else{printf("error\n");}if(HT[j].lc==0&&HT[j].rc==0){printf("%c",HT[j].elem);j=2*n-1;}ch=getchar();}}void OutputHuffmanCode(HuffmanTree HT,HuffmanCode HC,int n){int i;printf("\nnumber---element---weight---huffman code\n");for(i=1;i<=n;i++)printf(" %d %c %d %s\n",i,HT[i].elem,HT[i].weight,HC[i]);}int main(){HuffmanTree HT;HuffmanCode HC,t;Weight *w;char c,ch;// the symbolizes;int i,n,j; // the number of elements;int wei;// the weight of a element;printf("請輸入構建哈夫曼樹的結點數:" );scanf("%d",&n);w=(Weight *)malloc(n*sizeof(Weight));for(i=0;i<n;i++){//cout<<"請輸入第"<<i+1<<"個結點編號及其權值(如a 100):"<<endl;printf("請輸入結點編號及其權值(如a 100):" );scanf("%1s%d",&c,&wei);w[i].elem=c;w[i].m_weight=wei;}HuffmanCoding(HT,HC,w,n);OutputHuffmanCode(HT,HC,n);t=(HuffmanCode)malloc((n+1)*sizeof(char*));FILE *fp1;if((fp1=fopen("tra.txt","w"))==NULL){printf("無法建立檔案\n");exit(0);}Tree_printing(HT,n) ;ch=getchar();printf("輸入要輸入檔案的內容#號結束:");ch=getchar();while(ch!='#'){fputc(ch,fp1);ch=getchar();}fclose(fp1);if((fp1=fopen("tra.txt","r"))==NULL){printf("無法開啟檔案\n");exit(0);}int k=1;while(!feof(fp1)){ch=fgetc(fp1);printf("\n");for(j=1;j<=n;j++){if(ch==HT[j].elem ){printf("%s",HC[j]);t[k]=(char*)malloc((n)*sizeof(char));//putchar(HT[j].elem);t[k]=HC[j];k++;}}}fclose(fp1);FILE *fp;if((fp=fopen("yima.txt","w"))==NULL){printf("無法開啟檔案\n");exit(0);}for(i=1;i<n+1;i++){fputs(t[i],fp);}fclose(fp);for(j=1;j<k;j++)printf("%s",t[j]);printf("\n");OutputHuffman(HT,n);return 0 ;}