带权路径长度
设二叉树有n个带权值的叶子节点,那么从根节点到各个叶子节点的路径长度与相应节点权值的乘积的和,叫做二叉树的带权路径长度(WPL)
哈夫曼树:
具有最小带权路径长度的二叉树被称为哈夫曼树,或者最优二叉树
构造哈夫曼树
策略:要使WPL值最小,须使权值越大的叶子节点越靠近根节点,而权值越小的叶子节点越远离根节点
(1)给定的n个权值{W1,W2,W3…Wn}构造n棵只有一个叶子节点的二叉树,从而得到一个二叉树的集合F
(2)在F中选取根节点的权值最小和次小的两棵二叉树作为左、右子树,构造一棵新的二叉树,新的二叉树根节点的权值为其左、右子树根节点权值之和
(3)在集合F中删除作为左、右子树的两棵二叉树,并将新建立的二叉树加入到集合F中
(4)重复(2)、(3),当F中只剩下一棵二叉树时,这棵二叉树便是哈夫曼树
n个叶子节点的二叉树共有2n-1个节点
构造哈夫曼树存储及其生成算法
typedef struct
{
char data; //节点值
float weight; //权值
int parent; //双亲节点
int lchild; //左孩子节点
int rchild; //右孩子节点
} HTNode;
HTNode ht[2*N-1];
(1)n个叶子节点只有data域和weight域值,所有2n-1个节点parent、lchild、rchild域均设置为-1
(2)重复处理每个非叶子节点ht[i]~ht[2n-2]
从ht[0]~ht[i-1]中找出根节点(即parent为-1)最小的两个节点ht[lnode]和ht[rnode]
ht[lnode]和ht[rnode]作为左右子树,增加它们的双亲节点ht[i]
有:ht[i].weight=ht[lnode].weight+ht[rnode].weight
算法实现:
void CreatHT(HTNode ht[],int n)
{
int i,j,k,lnode,rnode;
float min1,min2;
for(i=0;i<2*n-1;i++)
ht[i].parent=ht[i].lchild=ht[i].rchild=-1;
for(i=n;i<2*n-1;i++)
{
//找出权值最小的两个节点
min1=min2=99999;
lnode=rnode=-1;
for(k=0;k
哈夫曼编码
’