#include <iostream>
#include <cstring>
using namespace std;
typedef struct HNode{
HNode(int w,int p,int l,int r)
:weight(w),
parent(p),
lchild(l),
rchild(r)
{}
unsigned int weight;
unsigned int parent,lchild,rchild;
}HNode,*HuffmanTree;
typedef char** HuffmanCode;
void Select(HuffmanTree HT,int n,int &s1,int &s2)
{
for (int i = 1; i <= n; ++i) {
if(!HT[i].parent){
s1=i;break;
}
}
for (int i = s1+1; i <= n; ++i) {
if(!HT[i].parent){
s2=i;break;
}
}
for (int i = s2; i <= n; ++i) {
if(!HT[i].parent&&HT[i].weight<=HT[s1].weight){
s2=s1;s1=i;
}
}
}
void HuffmanCoding(HuffmanTree&HT,HuffmanCode&HC,int *w,int n)
{
int m=2*n-1;
HT=(HuffmanTree)malloc((m+1)* sizeof(HNode));
HuffmanTree p;
int i=0;
for (i=1,p=HT+1;i<=n;i++,p++,w++) *p={*w,0,0,0};
for (;i<=m;i++,p++) *p={0,0,0,0};
for (i=n+1; i<=m ; ++i) {
int s1,s2;
Select(HT,i-1,s1,s2);
HT[s1].parent=i,HT[s2].parent=i;
HT[i].lchild=s1,HT[i].rchild=s2;
HT[i].weight=HT[s1].weight+HT[s2].weight;
}
HC=(HuffmanCode)malloc((n+1)* sizeof(char*));
char *cd=(char*)malloc(n* sizeof(char));
for (i=1; i<=n; i++) {
cd[n-1]='\0';
int c,f;
int start=n-1;
for (c=i,f=HT[i].parent; f; c=f,f=HT[f].parent) {
if (HT[f].lchild==c)cd[--start]='0';
else cd[--start]='1';
}
HC[i]=(char*)malloc((n-start)* sizeof(char));
strcpy(HC[i],&cd[start]);
}
free(cd);
for (i = 1; i <= n; ++i) {
cout<<"the Huffman Code of "<<i<<" is "<<HC[i]<<endl;
}
}
int main()
{
int n=5;
int *w;
for (int i = 1; i <= n; ++i) {
w[i]=i;
}
HuffmanTree HT;
HuffmanCode HC;
HuffmanCoding(HT,HC,w,n);
return 0;
}