#include<stdlib.h> #include<string.h> #include<stdio.h> #define MAX_Node_num 30 typedef 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+26 printf("下面打印赫夫曼树\n") ; coprint(p,HT); //p=HT+26 printf("打印工作结束\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 ; }