#include<iostream> #include<stdlib.h> #include<cstring> using namespace std; typedef struct hftree{ int might; int parent,lch,rch; char data; }*tree,node; typedef char** treecode; int length;//字符串长度; void chushi(tree &hf,int n)//初始话 { hf=new node[2*n]; for(int i=1;i<=2*n-1;i++) { hf[i].data='\0'; hf[i].might=0; hf[i].lch=0; hf[i].rch=0; hf[i].parent=0; } } void select(tree T,int n,int &s1,int &s2)//找出权值最小的两个; { int k,m; k=m=1000000; for(int j=1;j<=n;j++) { if(m>T[j].might&&T[j].parent==0) { m=T[j].might; s1=j; } } for(int i=1;i<=n;i++) { if(i!=s1&&k>T[i].might&&T[i].parent==0) { k=T[i].might; s2=i; } } } void hftree(tree &hf,int n)//创建霍夫曼树 { int s1,s2; if(n<=1) return; int m=2*n-1; for(int i=n+1;i<=m;++i) { select(hf,i-1,s1,s2); hf[s1].parent=i; hf[s2].parent=i; if(s1<=s2){ hf[i].lch=s1; hf[i].rch=s2; } else{ hf[i].lch=s2; hf[i].rch=s1; } hf[i].might=hf[s1].might+hf[s2].might; } } void codetree(tree hf,treecode &hc,int n)//获取字符的编码值 { int m,p; hc=new char*[n+1]; //指针数组; char *cd=new char[n]; //存放编码 cd[n-1]='\0'; for(int i=1;i<=n;i++) { int start=n-1; m=i; p=hf[i].parent; while(p!=0) { --start; if(hf[p].lch==m) { cd[start]='0'; } else cd[start]='1'; m=p; p=hf[p].parent; } hc[i]=new char[n-start]; strcpy(hc[i],&cd[start]); } delete []cd; } void input(tree &hf,int &n,char *date)//输入字符串 { char *a=date; int length_1; int num[256]={0}; int b[256]; int c[256]; cout<<"输入字符串:"; getchar(); gets(a); length_1=strlen(a); for(int i=0;i<length_1;i++) { num[(int)a[i]]++;//统计每个字符的权值 } n=0; for(int i=0;i<256;i++) { if(num[i]!=0) { b[n]=num[i]; c[n]=(char)i; ++n; } } hf=new node[2*n]; for(int i=1;i<=2*n-1;i++) { hf[i].data='\0'; hf[i].might=0; hf[i].lch=0; hf[i].rch=0; hf[i].parent=0; } for(int i=1;i<=n;i++) { hf[i].might=b[i-1]; hf[i].data=c[i-1]; } } int weizhi(tree hf,char *q,int n) //获取字符在树中的位置 { char *date=q; for(int j=1;j<=n;++j) { if(*date==hf[j].data) return j; } } void bianmachar(tree hf,char *q,treecode &result,int n)//对字符串编码 { char *date=q; char *cd; int m,p; result=new char * [length+1];//存放每个字符的编码值; cd=new char[n]; cd[n-1]='\0'; for(int i=0;i<length;++i) { m=weizhi(hf,&date[i],n);//获取每个字符在树中的位置 int start=n-1; p=hf[m].parent; while(p!=0) { --start; if(hf[p].lch==m) { cd[start]='0'; } else cd[start]='1'; m=p; p=hf[p].parent; } result[i+1]=new char[n-start]; strcpy(result[i+1],&cd[start]); } delete cd; } void chu(tree hf,treecode hc,treecode result,int n)//输出编码 { int m=2*n-1; cout<<"每个字符在树中的位置"<<endl; for(int i=1;i<=m;i++) { cout<<i<<" "<<hf[i].data<<" "<<hf[i].might<<" "<<hf[i].parent<<" "<<hf[i].lch<<" "<<hf[i].rch<<endl; } cout<<"每个字符的编码"<<endl; for(int i=1;i<=n;i++) { cout<<hf[i].data<<" "<<hc[i]<<endl; } cout<<"对字符串的编码:"; for(int j=1;j<=length;j++) { cout<<result[j]; } } void input_(tree &hf,int &n) //输入每个字符和对应的权值 { cout<<"输入字符和对应的权值"<<endl; for(int i=1;i<=n;i++) { cin>>hf[i].data; cin>>hf[i].might; } } void Decodehf(tree hf,char *m,int n)//译码 { char*date=m;//编码字符串 int LL=strlen(date);//编码字符串长度 char data[100];//解码字符串; int p=2*n-1;//获取根节点的位置; int j=0;//头指针 for(int i=0;i<length;i++) { if(date[i]=='0') p=hf[p].lch; else if(date[i]=='1') p=hf[p].rch; if(hf[p].lch==0&&hf[p].rch==0) { data[j]=hf[p].data; p=2*n-1; ++j; } } cout<<"对应编码:"; for(int k=0;k<j;k++) { cout<<data[k]; } cout<<endl; } void Xmb()//界面 { cout<<"\t\t\t------------------------------------------"<<endl; cout<<"\t\t\t|************霍夫曼编码译码**************|"<<endl; cout<<"\t\t\t|----------------------------------------|"<<endl; cout<<"\t\t\t|********1.对字符串进行编码译码**********|"<<endl; cout<<"\t\t\t|----------------------------------------|"<<endl; cout<<"\t\t\t|********2.输入字符的权值编码译码********|"<<endl; cout<<"\t\t\t------------------------------------------"<<endl; } int main() { char a; char date_1[100];//输入字符串统计权值 char date_2[100];//需要要编码的字符串 char date_3[100];//存储译码的字符串 tree hf; //hfm树 treecode hc;//存储每个字符的译码 treecode result;//存放译码的字符串 int n;//拥有权值的字符个数 while(1) { Xmb(); cout<<"输入相应命令:"; cin>>a; switch(a) { case '1': input(hf,n,date_1); hftree(hf,n);//创建霍夫曼树 codetree(hf,hc,n);//每个字符的编码 cout<<"输入需要编码的字符串:"; gets(date_2); length=strlen(date_2); bianmachar(hf,date_2,result,n);//字符串的编码 chu(hf,hc,result,n); cout<<endl; cout<<"输入需要译码的编码:" ; gets(date_3); Decodehf(hf,date_3,n); break; case '2': cout<<"输入字符个数:"; cin>>n; chushi(hf,n);//对霍夫曼树初始化 input_(hf,n);//输入字符和对应的权值 hftree(hf,n); codetree(hf,hc,n); cout<<"输入需要编码的字符串:"; getchar(); gets(date_2); length=strlen(date_2); bianmachar(hf,date_2,result,n); chu(hf,hc,result,n); cout<<endl; cout<<"输入需要译码的编码:" ; gets(date_3); Decodehf(hf,date_3,n); break; case '0': exit(0); } } }
文章来源: https://blog.csdn.net/weixin_43937576/article/details/90522445