#include<iostream>
using namespace std;
#define maxvalue 32376
#define MAXSIZE 1000
typedef struct
{
int weight;
int parent,lchild,rchild;
}HTNode,*HuffmanTree;
int Select(HuffmanTree HT,int n,int &s1,int &s2) //通过这个函数选出最小的两个权值;
{
int min1=maxvalue,min2=maxvalue,i;
for(i=1;i<=n;i++)
{
if((HT[i].parent==0)&&HT[i].weight<min1) //选出最小的一个权值;
{
min1=HT[i].weight;
s1=i;
}
if((HT[i].parent==0)&&(HT[i].weight<min2)) //选出第二小的权值;
if(i!=s1)
{
min2=HT[i].weight;
s2=i;
}
}
}
int CreateHuffmanTree(HuffmanTree &HT,int n)
{
int m,i,j,s1,s2,WPL=0;
m=2*n-1;
HT=new HTNode[MAXSIZE]; //为结点开辟空间;
for(i=1;i<=m;i++)
{
HT[i].parent=0;HT[i].lchild=0;HT[i].rchild=0; //初始化,使每个结点的父结点和左右孩
子下标为0;
}
for(i=1;i<=n;i++)
cin>>HT[i].weight;
for(i=n+1;i<=m;i++) //通过次循环为第n+1到m个结点赋权值;
{
Select(HT,i-1,s1,s2); //从本结点的前面n个结点选出权值最小的
两个结点;
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;
}
for(i=1;i<=m;i++)
cout<<HT[i].weight<<" ";
cout<<endl;
for(i=n+1;i<=m;i++) //哈夫曼树构造完成后,计算WPL;
WPL+=HT[i].weight;
cout<<WPL;
}
int main()
{
HuffmanTree HT;
int i,n;
cin>>n;
CreateHuffmanTree(HT,n);
return 0;
}
已知,w={2,4,8,3,9}.
结点 | weight | parent | lchild | rchild |
1 | 2 | 0 | 0 | 0 |
2 | 4 | 0 | 0 | 0 |
3 | 8 | 0 | 0 | 0 |
4 | 3 | 0 | 0 | 0 |
5 | 9 | 0 | 0 | 0 |
6 | - | 0 | 0 | 0 |
7 | - | 0 | 0 | 0 |
8 | - | 0 | 0 | 0 |
9 | - | 0 | 0 | 0 |
结点 | weight | parent | lchild | rchild |
1 | 2 | 6 | 0 | 0 |
2 | 4 | 7 | 0 | 0 |
3 | 8 | 8 | 0 | 0 |
4 | 3 | 6 | 0 | 0 |
5 | 9 | 7 | 0 | 0 |
6 | 5 | 8 | 1 | 4 |
7 | 9 | 9 | 2 | 5 |
8 | 13 | 9 | 3 | 6 |
9 | 22 | 0 | 7 | 8 |
结点示意图
为什么在代码中WPL的值是
for(i=n+1;i<=m;i++)
WPL+=HT[i].weight ?
因为从第n+1个结点开始后的结点每一次与后续结点相加,它的子结点的权值也包含在其中,所以求wpl值我们只需要将第n+1到m个结点的权值相加就行。