#include<iostream>
using namespace std;
#define maxn 100
int huffTreeN;//树中的节点个数初始化为n
int i1=1,i2=2;
struct element{//存储字符
double weight;//字符出现的概率为实数,次程序为了简便,不计算其概率,而直接用其出现的次数代替
int lchild;//该节点的左孩子在huffTree[]数组中的下标
int rchild;//该节点的右孩子在huffTree[]数组中的下标
int parent; //该节点的双亲节点在huffTree[]数组中的下标
//bool hasparent;//记录该节点是否有双亲节点
};
void Select(element *huffTree) {
int i,j;
for(i = 0;i <huffTreeN;i++)//选一个没有双亲的节点初始化
if(huffTree[i].parent==-1)
{
i1 = i;
break;
}
for(j = 0;j <huffTreeN;j++)//选择一个没有双亲节点和不等同于j的节点
if(huffTree[j].parent==-1&&i!=j)
{
i2 = j;
break;
}
for(i = 0;i <huffTreeN;i++)
if((huffTree[i].parent==-1)&&(huffTree[i1].weight>=huffTree[i].weight)&&i2!=i)
i1=i;
for(j = 0;j <huffTreeN;j++)
if((huffTree[j].parent==-1)&&(huffTree[i2].weight>huffTree[j].weight)&&(i1!=j))
i2=j;
}
//构建哈夫曼树
void HuffmanTree(element huffTree[],int n){
for(int i=0;i<2*n-1;i++){//初始化哈夫曼树中2*n-1个节点
huffTree[i].parent=-1;
huffTree[i].lchild=-1;
huffTree[i].rchild=-1;
//huffTree[i].hasparent=false;
}
cout<<"huffTreeN:"<<huffTreeN<<endl;
//int tempHn=huffTreeN;
for(int k=n;k<2*n-1;k++){
Select(huffTree);//在huffTree中找权值最小的两个节点I1和I2
cout<<"选出当前最小的两个节点:"<<endl;
cout<<"i1:"<<i1<<" "<<"i2:"<<i2<<endl;
huffTree[i1].parent=k;
huffTree[i2].parent=k;
huffTree[k].weight=huffTree[i1].weight+huffTree[i2].weight;
huffTree[k].lchild=i1;
huffTree[k].rchild=i2;
huffTreeN++;//加入双亲节点之后,huffTree数组中的节点树加一
}
}
//哈夫曼编码
void HuffmanCode(element huffTree[],int n){
int s[2*n-1];//存放每个叶子节点的哈夫曼编码
for(int i=0;i<n;i++){//在huffTree[]中前n个元素是叶子节点,需要编码
int k=0;
int temp=huffTree[i].parent;
int l=i;
while(temp!=-1){
if(huffTree[temp].lchild==l){
s[k]=0;
k++;
}
if(huffTree[temp].rchild==l){
s[k]=1;
k++;
}
l=temp;
temp=huffTree[temp].parent;
}
cout<<"节点 "<<i+1<<"的哈夫曼编码是:";
for(int j=k-1;j>=0;j--)
cout<<s[j];
cout<<endl;
}
}
int main(){
int n;//字符个数
cout<<"字符个数:"<<endl;
cin>>n;
element *huffTree=new element[2*n-1];//动态分配内存存放节点
huffTreeN=n;//树中的节点个数初始化为n
for(int i=0;i<n;i++){
cout<<"输入字符 "<<i+1<<" 的权值(出现的次数):";
cin>>huffTree[i].weight;
}
HuffmanTree(huffTree,n);
HuffmanCode(huffTree,n);
delete huffTree;
return 0;
}