哈夫曼编码
来源:互联网 发布:广联达软件专用电脑 编辑:程序博客网 时间:2024/06/06 16:26
#include<iostream.h>const int MAX=20;//哈夫曼树输入数据的结构struct huffinit{ char data; int weight;};//哈夫曼树结点的结构struct huffnode{ int weight; int lchild,rchild,parent;};//哈夫曼树编码的结构struct huffcode{ char data; char code[MAX+1];};huffnode tree[2*MAX-1]; //存huffman树huffcode cd[MAX]; //存编码信息int size; //叶子结点个数void Select(int &min1,int &min2,int m){ min1=min2=0; int m1=32767,m2; int i,t; for(i=0;i<m;i++) { if(tree[i].parent==-1) if(tree[i].weight<m1) { m2=m1; min2=min1; m1=tree[i].weight; min1=i; } else if(tree[i].weight<m2) { m2=tree[i].weight; min2=i; } } if(min1>min2) { t=min1; min1=min2; min2=t; }}void HuffTree(huffinit w[],int n){ int i; for(i=0;i<2*n-1;i++)//初始化,所有的结点均没有双亲和孩子 { tree[i].parent=-1; tree[i].lchild=-1; tree[i].rchild=-1; } for(i=0;i<n;i++)//构造出n颗只含有根节点的二叉树 { cd[i].data=w[i].data;//结点值 tree[i].weight=w[i].weight;//权值 } int k,i1,i2; for(k=n;k<2*n-1;k++)//经过n-1次合并 { Select(i1,i2,k);//查找出最小的两个根节点,下标为i1,i2 tree[i1].parent=k;//将i1和i2合并,且i1和i2的双亲为k tree[i2].parent=k; tree[k].weight=tree[i1].weight+tree[i2].weight; tree[k].lchild=i1; tree[k].rchild=i2; } size=n;}void Output()//输出哈夫曼树各节点的信息{ int i; cout<<"已建好的哈夫曼树各结点信息为:"<<endl; for(i=0;i<2*size-1;i++) cout<<tree[i].weight<<" "<<tree[i].parent<<" "<<tree[i].lchild<<" "<<tree[i].rchild<<endl;}void Encode()//对结点进行编码{ int i; for(i=0;i<size;i++) { char code[MAX+1]; int start=MAX+1; int parent=tree[i].parent; int position=i; while(parent!=-1) { start--; if(tree[parent].lchild==position)code[start]='0'; elsecode[start]='1'; position=parent; parent=tree[parent].parent; } int j=0; while(start<=MAX) { cd[i].code[j]=code[start]; j++; start++; } cd[i].code[j]='\0'; }}void OutCode()//输出哈夫曼树的各节点编码{ int i; cout<<"已建好的哈夫曼树各结点编码为:"<<endl; for(i=0;i<size;i++) cout<<cd[i].data<<"--->"<<cd[i].code<<endl;}void Decode(char code[])//解码操作{ int i=0; int j=2*(size-1); //从根开始 char dec[MAX]; //暂存已解出的字符 int k=0; while(code[i]!='\0') { if(code[i]=='0') j=tree[j].lchild; else j=tree[j].rchild; if(tree[j].lchild==-1) { dec[k++]=cd[j].data; j=2*(size-1); } i++; } dec[k]='\0'; //密码串读完时,若没同时达到叶子(未重新回到根),则密码串有误 if(j!=2*(size-1)&&tree[j].lchild!=-1) cout<<"此密码串无解!"; else cout<<dec; cout<<endl;}void main(){ huffinit info[MAX]; int i,n; cin>>n; for(i=0;i<n;i++) { cin>>info[i].data; cin>>info[i].weight; } HuffTree(info,n); Output();//节点信息 cout<<endl; Encode();//进行编码 OutCode();//已建好的哈夫曼树的结点编码信息 cout<<endl; char flag='Y'; do{ cout<<"请输入密码:"; char code[30]; cin>>code; cout<<"解码结果为:"; Decode(code);//进行解码 cout<<endl; cout<<"还继续解码吗?(Y/N)"; cin>>flag; }while(flag=='Y'||flag=='y');}