#include<iostream>
#include<cstring>
using namespace std;
struct HuffmanNode
{
int weight;
int Lchild,Rchild;
int parent;
};
void select(HuffmanNode *HT,int i,int &s1,int &s2)
{
int a,min1=0,min2=0;
for(a=1;a<=i;a++)
{
if(HT[a].parent==0&&min1==0||HT[a].parent==0&&min2==0)
{
if(HT[a].parent==0&&min1==0)min1=a;
else if(HT[a].parent==0&&min2==0)min2=a;
}
else if(HT[a].parent==0&&HT[a].weight<HT[min1].weight||HT[a].parent==0&&HT[a].weight<HT[min2].weight)
if(HT[a].weight<HT[min1].weight&&HT[min1].weight>HT[min2].weight)
min1=a;
else if(HT[a].weight<HT[min1].weight&&HT[min1].weight<HT[min2].weight)
{
min2=min1;
min1=a;
}
else if(HT[a].weight<HT[min2].weight&&HT[min2].weight>HT[min1].weight)
min2=a;
else if(HT[a].weight<HT[min2].weight&&HT[min1].weight>HT[min2].weight)
{
min1=min2;
min2=a;
}
}
s1=min1;s2=min2;
}
void CreateHuffmanTree(HuffmanNode* &HT,int n)
{
if(n<=1) return ;
int m=2*n-1,i,s1,s2;
HT=new HuffmanNode[m+1];
for(i=1;i<=m;i++)
{
HT[i].Lchild=0;
HT[i].parent=0;
HT[i].Rchild=0;
}
cout<<"请输入各节点的权值,以空格间隔。"<<endl;
for(i=1;i<n+1;i++)
cin>>HT[i].weight;
for(i=n+1;i<=m;i++)
{
select(HT,i-1,s1,s2);
HT[i].Lchild=s1;
HT[i].Rchild=s2;
HT[s1].parent=i;
HT[s2].parent=i;
HT[i].weight=HT[s1].weight+HT[s2].weight;
}
}
void createHuffmanCode(HuffmanNode *HT,char** &HC,int n)
{
HC= new char*[n+1];
char *cd=new char[n];
cd[n-1]='\0';
int i,c,p,start;
for(i=1;i<=n;i++)
{
c=i;p=HT[i].parent;start=n-2;
while(p!=0)
{
if(HT[p].Lchild==c) cd[start]='0';
else cd[start]='1';
start--;
c=p;
p=HT[p].parent;
}
HC[i]=new char[n-start-1];
strcpy(HC[i],&cd[start+1]);
}
delete cd;
}
int main()
{
char **HC;
int n;
cout<<"请输入哈夫曼树的叶子节点个数:"<<endl;
cin>>n;
HuffmanNode *HT;
CreateHuffmanTree(HT,n);
int i;
cout<<"哈夫曼树为:"<<endl;
for(i=1;i<=2*n-1;i++)
cout<<i<<" "<<HT[i].weight<<" "<<HT[i].parent<<" "<<HT[i].Lchild<<" "<<HT[i].Rchild<<endl;
createHuffmanCode(HT,HC,n);
cout<<"对应的哈夫曼编码为:"<<endl;
for(i=1;i<=n;i++)
cout<<HT[i].weight<<":"<<HC[i]<<endl;
}