#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';
else
code[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');
}
哈夫曼编码
最新推荐文章于 2022-06-07 23:56:00 发布