哈夫曼树——C++实现

来源:互联网 发布:手机健康体检软件 编辑:程序博客网 时间:2024/05/21 02:33
#include <iostream> using namespace std; #define MAXBIT 10#define MAXVALUE 10000#define MAXLEAF 100#define MAXNODE MAXLEAF*2-1 //定义哈夫曼树编码类型typedef struct{char bit[MAXBIT];//存放叶子结点字符编码过后的二进制编码 int start;//存放叶子结点二进制编码在code[]数组里的起始数组位置int length;//存放二进制编码的位数}CodeType;   //定义哈夫曼树结点类型typedef struct {char ch;//字符int weight;//哈夫曼树结点的权值int lchild,rchild,parent;//哈夫曼树结点的左孩子,右孩子,父节点}Htnode;   void createHFMTree(Htnode h[MAXNODE],int n);//构造哈夫曼树void showCode(CodeType code[MAXNODE],Htnode h[MAXNODE],int n);//显示叶子的字符和其对应的二进制编码void compileCode(char str[],int n,CodeType code[MAXLEAF],Htnode h[MAXNODE]);//输入字符串,得到二进制编码void decompileCode(char num[],int n,CodeType code[MAXLEAF],Htnode h[MAXNODE]);//输入二进制编码得到字符串void main(){Htnode h[MAXNODE]; CodeType code[MAXLEAF]; char str[100];//存放输入的需要编译的的字符串char num[100];//存放输入的需要编译的二进制字符串int n;//输入的叶子结点数//哈夫曼编码器cout<<"-----------------哈夫曼编码器------------------\n";cout<<"请输入叶子结点数:"; cin>>n;createHFMTree(h,n);showCode(code,h,n);//哈夫曼译码器cout<<"-----------------哈夫曼译码器------------------\n";cout<<"请输入字符:\n";cin>>str;compileCode(str,n,code,h);cout<<"请输入需要译码的编码:\n";cin>>num;decompileCode(num,n,code,h);}//构造哈夫曼树void createHFMTree(Htnode h[MAXNODE],int n){ int i,j,m1,m2,s1,s2; for(i=0;i<2*n-1;i++){//所有节点初始化h[i].weight=0; h[i].parent=-1; h[i].lchild=-1; h[i].rchild=-1; }cout<<"请输入叶子节点的字符:";for(i=0;i<n;i++){ getchar();cin>>h[i].ch;} cout<<"请输入叶子节点的权重:";for(i=0;i<n;i++){   getchar();cin>>h[i].weight;}for(i=0;i<n-1;i++){m1=m2=MAXVALUE;//m1和m2存储叶子结点权值的最小值和次小值s1=s2=0;//s1和s2存储m1和m2的位置for(j=0;j<n+i;j++){if(h[j].weight<m1&&h[j].parent==-1){ m2=m1;s2=s1;m1=h[j].weight;s1=j; } else if(h[j].weight<m2&&h[j].parent==-1){ m2=h[j].weight;s2=j; } } h[n+i].weight=h[s1].weight+h[s2].weight;//父结点的权重是左孩子和右孩子的权重之和h[s1].parent=h[s2].parent=n+i; h[n+i].lchild=s1;h[n+i].rchild=s2;}}//显示叶子的字符和其对应的二进制编码void showCode(CodeType code[MAXNODE],Htnode h[MAXNODE],int n){int i,j,k,c,p;    CodeType cd;for(i=0;i<n;i++){ code[i].length=0;code[i].start=0;k=code[i].start;cd.start=n-1;c=i; p=h[c].parent; while(p!=-1){//有父节点 if(h[p].lchild==c)//孩子是父节点的左孩子cd.bit[cd.start]='0'; elsecd.bit[cd.start]='1'; cd.start--;  c=p;  p=h[c].parent;  } for(j=cd.start+1;j<n;j++,k++){ code[i].bit[k]=cd.bit[j];   code[i].length++;  //length计算存放的二进制编码的位数} }for(i=0;i<n;i++){ //输出每个叶子节点的哈夫曼编码  cout<<h[i].ch<<"的编码是:";for(j=code[i].start;j<code[i].length;j++)cout<<code[i].bit[j]; cout<<endl;  }}//输入字符串,得到二进制编码void compileCode(char str[],int n,CodeType code[MAXLEAF],Htnode h[MAXNODE]){for(int i=0;str[i]!='\0';i++){for(int j=0;j<n;j++){if(str[i]==h[j].ch){for(int k=code[j].start;k<code[j].length;k++)cout<<code[j].bit[k];}}cout<<" ";}cout<<endl<<endl;}//输入二进制编码得到字符串void decompileCode(char num[],int n,CodeType code[MAXLEAF],Htnode h[MAXNODE]){int j=2*n-2;  //哈夫曼树根结点的位置for(int i=0;num[i]!='\0';i++){if(num[i]=='0'){j=h[j].lchild;}else if(num[i]=='1'){j=h[j].rchild;}if(j<n){   //j大于等于n表示的都是除叶子结点以外的哈夫曼树结点   cout<<h[j].ch<<" ";j=2*n-2;}}cout<<endl;}

0 0
原创粉丝点击