#include<iostream>
using namespace std;
#define Max 15
typedef struct
{
unsigned weight;
unsigned p;
unsigned lc;
unsigned rc;
}HTNode;
int findmin(HTNode* huf,int n,int m);
int main()
{
int i,j=0,k=0;
int m=-1;
int str[8][5];
int str2[8][5];
cout<<" Problem "<<endl;
cout<<" 某系统在通信联络中只可能出现八种字符(A,B,C,D,E,F,G,H),其使用概率分别为0.05、0.29、0.07、0.08、0.14、0.23、0.03、0.11,如何设计这些字符的二进制编码,以使通信中总码长尽可能短?"<<endl;
int ar[8]={ 5, 29, 7, 8, 14, 23, 3, 11};
HTNode huf[16];
int min1,min2;
for(i=0;i<8;i++)
huf[i].weight=ar[i];
for(i=0;i<16;i++)
huf[i].p=huf[i].lc =huf[i].rc =0;
for(i=8;i<15;i++)
{
min1=findmin(huf,i,m);
m=min1;
min2=findmin(huf,i,m);
huf[i].weight =huf[min1].weight +huf[min2].weight ;
huf[i].lc =min1;
huf[i].rc =min2;
huf[min1].p=huf[min2].p=i;
m=-1;
}
huf[i-1].p=15;
cout<<"数组方式存储的树如下: "<<endl;
cout<<"权值 "<<"双亲节点 "<<"左孩子节点 "<<" 右孩子节点 "<<endl;
for(i=0;i<15;i++)
cout<<huf[i].weight <<" "<<huf[i].p<<" "<<huf[i].lc <<" "<<huf[i].rc <<endl;
for(i=0;i<8;i++)
{
k=i;
while(k<14)
{
m=k;
k=huf[k].p;
if(m==huf[k].lc)
str[i][j++]=0;
else
str[i][j++]=1;
}
str[i][j]=-1;
j=0;
}
for(i=0;i<8;i++)
{
j=0;
while(str[i][j]!=-1)
j++;
for(m=0;m<j;m++)
str2[i][m]=str[i][j-1-m];
str2[i][m]=-1;
}
char ch='A';
cout<<"各字符的赫夫曼编码是: "<<endl;
for(i=0;i<8;i++)
{
j=0;
cout<<char(ch+i)<<" : ";
while(str2[i][j]!=-1)
cout<<str2[i][j++]<<" ";
cout<<endl;
}
cout<<"最短的通信总码长度为 : "<<endl;
double sum=0;
for(i=0;i<8;i++)
{
j=0;
while(str[i][j]!=-1)
j++;
sum+=ar[i]*j;
}
cout<<sum/100<<endl;
return 0;
}
int findmin(HTNode* huf,int n,int m)
{
int i,min,j;
for(i=0;i<=n;i++)
if(huf[i].p==0&&i!=m)
{min=i;break;}
for( j=i;j<=n;j++)
if(huf[j].p==0)
if(huf[j].weight <huf[min].weight &&j!=m)
min=j;
return min;
}