#include<iostream.h>//该程序实验哈夫曼树的建立、编码、译码三个基本功能 #include<stdio.h> #include<stdlib.h> #include<string.h> #include<fstream.h> typedef struct{ //结构体 char ch; //字符 int weight; //权值 int parent,lchild,rchild; }htnode,*hfmtree; typedef char **hfmcode; void Select(hfmtree &HT,int a,int *p1,int *p2) //选出HT树到a为止,权值最小且parent为0的2个节点 { int i,j,x,y; for(j=1;j<=a;++j){ if(HT[j].parent==0){ x=j; break; } } for(i=j+1;i<=a;++i){ if(HT[i].weight<HT[x].weight&&HT[i].parent==0){ x=i; //选出最小的节点 } } for(j=1;j<=a;++j) { if(HT[j].parent==0&&x!=j) { y=j; break; } } for(i=j+1;i<=a;++i) { if(HT[i].weight<HT[y].weight&&HT[i].parent==0&&x!=i) { y=i; //选出次小的节点 } } if(x>y){ *p1=y; *p2=x; } else { *p1=x; *p2=y; } } void hfmcoding(hfmtree &HT,hfmcode &HC,int n) //构建哈夫曼树HT,并求出n个字符的赫夫曼编码HC { int i,start,c,f,m,w; int p1,p2; char *cd,z; if(n<=1){ return; } m=2*n-1; HT=(hfmtree)malloc((m+1)*sizeof(htnode)); for(i=1;i<=n;++i) //初始化n个叶子结点 { cout<<"请输入第"<<i<<"字符信息和权值:"; cin>>z>>w; HT[i].ch=z; HT[i].weight=w; HT[i].parent=0; HT[i].lchild=0; HT[i].rchild=0; } for(;i<=m;++i) //初始化其余的结点 { HT[i].ch='0'; HT[i].weight=0; HT[i].parent=0; HT[i].lchild=0; HT[i].rchild=0; } for(i=n+1;i<=m;++i) //建立哈夫曼树 { Select(HT,i-1,&p1,&p2); HT[p1].parent=i; HT[p2].parent=i; HT[i].lchild=p1; HT[i].rchild=p2; HT[i].weight=HT[p1].weight+HT[p2].weight; } HC=(hfmcode)malloc((n+1)*sizeof(char *)); cd=(char *)malloc(n*sizeof(char)); cd[n-1]='\0'; for(i=1;i<=n;++i) //给n个字符编码 { start=n-1; for(c=i,f=HT[i].parent;f!=0;c=f,f=HT[f].parent) { if(HT[f].lchild==c) { cd[--start]='0'; } else { cd[--start]='1'; } } HC[i]=(char*)malloc((n-start)*sizeof(char)); strcpy(HC[i],&cd[start]); } free(cd); } int main() { char code[100],h[100],hl[100]; int n,i,j,k,l; ifstream input; //文件输入输出流 ofstream output; char str[100]; int choice=0; //choice作为输入输出选项 hfmtree HT; hfmcode HC; while(choice!=4) { cout<<" "<<"*************************哈夫曼编码/译码器*************************\n"; cout<<" "<<"1.Initialization"<<" "<<"2.Encoding"<<" "<<"3.Decoding"<<" "<<"4.Exit\n"; cout<<"请输入您的选项(*表示空格):"; cin>>choice; if(choice==1) //初始化 { cout<<"请输入字符个数:"; cin>>n; hfmcoding(HT,HC,n); for(i=1;i<=n;++i) { cout<<HT[i].ch<<":"<<HC[i]<<endl; } output.open("hfmTree.txt"); if(!output){ cout<<"can't oen file!"<<endl; return 1; } for(i=1;i<=n;i++) { output<<HT[i].ch<<" "<<HC[i]<<endl; } output.close(); cout<<"哈夫曼树已经创建完毕,并且已经放入hfmTree.txt文件中!"<<endl; } else if(choice==2) //进行编码,并将字符放入ToBeTran.txt,码值放入CodeFile.txt中 { cout<<"请输入字符:"; gets(str); output.open("ToBeTran.txt"); if(!output) { cout<<"can't open file!"<<endl; return 1; } output<<str<<endl; output.close(); output.open("CodeFile.txt"); if(!output){ cout<<"can't open file!"<<endl; return 1; } for(i=0;i<strlen(str);i++){ for(j=0;j<=n;++j) { if(HT[j].ch==str[i]) { output<<HC[j]; break; } } } output.close(); cout<<"\n"; cout<<"编码完毕,并且已经存入CodeFile.txt文件!\n"; input.open("CodeFile.txt"); //从CodeFile.txt中读入编码,输出在终端 if(!input) { cout<<"can't oen file!"<<endl; return 1; } input>>code; cout<<"编码码值为:"<<code<<endl; input.close(); } else if(choice==3) //读入CodeFile.txt中的编码进行译码,将译出来的字符放入Textfile.txt中 { input.open("CodeFile.txt"); if(!input){ cout<<"can't open file!"<<endl; return 1; } input>>h; input.close(); output.open("Textfile.txt"); if(!output) { cout<<"can't open file!"<<endl; return 1; } k=0; while(h[k]!='\0') //先用编码中的前几个和字符的编码相比较,然后往后移 { for(i=1;i<=n;i++){ l=k; for(j=0;j<strlen(HC[i]);j++,l++){ hl[j]=h[l]; } hl[j]='\0'; if(strcmp(HC[i],hl)==0) { output<<HT[i].ch; k=k+strlen(HC[i]); break; } } } output.close(); input.open("Textfile.txt"); if(!input){ cout<<"can't open file!"<<endl; return 1; } input>>h; cout<<h<<endl; input.close(); cout<<"译码结束,字符已经存入Textfile.txt文件中!"<<endl; } else if(choice==4) //退出 { exit(0); } else //不存在该选项则重新选择 { cout<<"输入有误,请重新输入!"<<endl; } cout<<endl; } return 0; }
Huffman Code
最新推荐文章于 2022-05-18 21:51:30 发布