#include <iostream>
using namespace std;
#define MAXVALUE 1000
#define N 100
typedef struct
{
int weight;
char data;
int parent;
int lchild;
int rchild;
}HNodeType;
typedef struct{
int bit[N]; //用来保存字符的哈弗曼编码
int start; //表示该编码在数组中的起始位置
}HCodeType;
//n为叶子节点的个数
void menu()
{
printf("请输入您要完成的功能所对应的序号:\n");
printf("1.构造哈弗满树\n");
printf("2.求哈夫曼编码\n");
printf("3.对给定数据加密\n");
printf("4.对密文进行解密\n");
printf("0.退出程序\n");
}
void Create_HaffmanTree(HNodeType HFMTree[],int n ) //构造哈夫曼树于HFMTree[ ],n为叶子节点的个数
{
int m1,x1,m2, x2, i,j;
for (i=0;i<2*n-1;i++) //数组HuffNode[ ]初始化
{
HFMTree[i].weight=0;
HFMTree[i].parent=-1;
HFMTree[i].lchild=-1;
HFMTree[i].rchild=-1;
}
for (i=0;i<n;i++)
{
cout<<"请输入第" << i+1 << "个叶子节点的值:";
cin>> HFMTree[i].data ; //输入n个叶子节点的数据
cout<<"请输入第" << i+1 << "个叶子节点的权重:";
cin>> HFMTree[i].weight ; //输入n个叶子结点的权值
cout<<endl;
}
for (i=0;i<n-1;i++) //构造哈夫曼树
{
x1=x2=MAXVALUE;
m1=m2=0;
for (j=0;j<n+i;j++) //选取最小和次小两个权值
{
if (HFMTree[j].parent==-1&& HFMTree[j].weight<x1)
{
x2=x1;
m2=m1;
x1= HFMTree[j].weight;
m1=j;
}
else if (HFMTree[j].parent==-1 && HFMTree[j].weight<x2)
{
x2=HFMTree[j].weight;
m2=j;
}
}//以下是将找出的两棵子树合并为一棵子树
HFMTree [m1].parent=n+i;
HFMTree [m2].parent=n+i;
HFMTree [n+i].weight =HFMTree [m1].weight+HFMTree [m2].weight;
HFMTree [n+i].lchild=m1;
HFMTree [n+i].rchild=m2;
}
}
void HaffmanCode(HNodeType HFMTree[], HCodeType HuffCode[ ],int n)
{
HCodeType cd; //字符编码的缓冲变量
int i,j,c,p;
for(i=0;i<n;i++) //求每个叶子结点的哈夫曼编码
{
cd.start=n-1;
c=i;
p=HFMTree[c].parent; //注意c和p的关系
while (p!=-1) //由叶子结点向上直到树根
{
if (HFMTree[p].lchild==c)
cd.bit[cd.start]=0;
else
cd.bit[cd.start]=1;
cd.start--;
c=p;
p=HFMTree[c].parent;
}
for (j=cd.start+1;j<n;j++) //保存求出的每个叶结点的哈夫曼编码和编码的起始
位
HuffCode[i].bit[j]=cd.bit[j];
HuffCode[i].start=cd.start+1;
} //求每个叶子结点的哈夫曼编码
for (i=0;i<n;i++) //输出每个叶子结点的哈夫曼编码
{
cout<<HFMTree[i].data <<endl;
for (j=HuffCode[i].start;j<n;j++)
cout<<HuffCode[i].bit[j];
cout << endl;
}
}
void main()
{
HNodeType bt[MAXVALUE];
HCodeType bt1[MAXVALUE];
int n,note;
while(1)
{
menu();
cin>>note;
switch(note)
{
case 1:
cout<<"请输入叶子节点的数量:"<<endl;
cin>>n;
cout<<endl;
Create_HaffmanTree(bt,n);
break;
case 2: HaffmanCode(bt,bt1,n);
break;
case 3: break;
case 4: break;
case 0: exit(0);
}
}
using namespace std;
#define MAXVALUE 1000
#define N 100
typedef struct
{
int weight;
char data;
int parent;
int lchild;
int rchild;
}HNodeType;
typedef struct{
int bit[N]; //用来保存字符的哈弗曼编码
int start; //表示该编码在数组中的起始位置
}HCodeType;
//n为叶子节点的个数
void menu()
{
printf("请输入您要完成的功能所对应的序号:\n");
printf("1.构造哈弗满树\n");
printf("2.求哈夫曼编码\n");
printf("3.对给定数据加密\n");
printf("4.对密文进行解密\n");
printf("0.退出程序\n");
}
void Create_HaffmanTree(HNodeType HFMTree[],int n ) //构造哈夫曼树于HFMTree[ ],n为叶子节点的个数
{
int m1,x1,m2, x2, i,j;
for (i=0;i<2*n-1;i++) //数组HuffNode[ ]初始化
{
HFMTree[i].weight=0;
HFMTree[i].parent=-1;
HFMTree[i].lchild=-1;
HFMTree[i].rchild=-1;
}
for (i=0;i<n;i++)
{
cout<<"请输入第" << i+1 << "个叶子节点的值:";
cin>> HFMTree[i].data ; //输入n个叶子节点的数据
cout<<"请输入第" << i+1 << "个叶子节点的权重:";
cin>> HFMTree[i].weight ; //输入n个叶子结点的权值
cout<<endl;
}
for (i=0;i<n-1;i++) //构造哈夫曼树
{
x1=x2=MAXVALUE;
m1=m2=0;
for (j=0;j<n+i;j++) //选取最小和次小两个权值
{
if (HFMTree[j].parent==-1&& HFMTree[j].weight<x1)
{
x2=x1;
m2=m1;
x1= HFMTree[j].weight;
m1=j;
}
else if (HFMTree[j].parent==-1 && HFMTree[j].weight<x2)
{
x2=HFMTree[j].weight;
m2=j;
}
}//以下是将找出的两棵子树合并为一棵子树
HFMTree [m1].parent=n+i;
HFMTree [m2].parent=n+i;
HFMTree [n+i].weight =HFMTree [m1].weight+HFMTree [m2].weight;
HFMTree [n+i].lchild=m1;
HFMTree [n+i].rchild=m2;
}
}
void HaffmanCode(HNodeType HFMTree[], HCodeType HuffCode[ ],int n)
{
HCodeType cd; //字符编码的缓冲变量
int i,j,c,p;
for(i=0;i<n;i++) //求每个叶子结点的哈夫曼编码
{
cd.start=n-1;
c=i;
p=HFMTree[c].parent; //注意c和p的关系
while (p!=-1) //由叶子结点向上直到树根
{
if (HFMTree[p].lchild==c)
cd.bit[cd.start]=0;
else
cd.bit[cd.start]=1;
cd.start--;
c=p;
p=HFMTree[c].parent;
}
for (j=cd.start+1;j<n;j++) //保存求出的每个叶结点的哈夫曼编码和编码的起始
位
HuffCode[i].bit[j]=cd.bit[j];
HuffCode[i].start=cd.start+1;
} //求每个叶子结点的哈夫曼编码
for (i=0;i<n;i++) //输出每个叶子结点的哈夫曼编码
{
cout<<HFMTree[i].data <<endl;
for (j=HuffCode[i].start;j<n;j++)
cout<<HuffCode[i].bit[j];
cout << endl;
}
}
void main()
{
HNodeType bt[MAXVALUE];
HCodeType bt1[MAXVALUE];
int n,note;
while(1)
{
menu();
cin>>note;
switch(note)
{
case 1:
cout<<"请输入叶子节点的数量:"<<endl;
cin>>n;
cout<<endl;
Create_HaffmanTree(bt,n);
break;
case 2: HaffmanCode(bt,bt1,n);
break;
case 3: break;
case 4: break;
case 0: exit(0);
}
}