哈夫曼树 小讲

    给定n个权值作为n个叶子结点,构造一棵二叉树,若带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman tree)。哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近。

    在一棵树中,从一个结点往下可以达到的孩子或孙子结点之间的通路,称为路径。通路中分支的数目称为路径长度。

    树的带权路径长度规定为所有叶子结点的带权路径长度之和,记为WPL。

    如下图所示,权值分别为1 2 3 4 的叶子节点,可以构造出4颗形状不同的二叉树,(下图仅列出两个),他们的带权路径长度分别为:

   

    图1、 WPL = 1 * 2 + 2 * 2 + 3 * 2 + 4 * 2 = 20

    图2、 WPL = 1 * 3 + 2 * 3 + 3 * 2 + 4 * 1 = 19

   我们把最小的带权路径长度的二叉树称作哈夫曼树,或 最优二叉树, 图2 所示的二叉树是一棵哈夫曼树。

    建树的步骤:

    1、 给定对应的n 个权值,是对应节点构成n棵 二叉树的森林T, 每一个二叉树Ti 中都只有一个带权值为Wi 的根节点,其左右子树均为空。

    2、 选取两个节点权值最小的子树分别作为左右子树构造一棵新的二叉树,且置新的二叉树的根节点的权值为器左右子树上根节点的权值之和

    3、 在森林T 中,用新得到的二叉树代替选取的两棵树。

    4、 重复2. 3 ,直到T 只喊一个树为止,得到的便是哈夫曼树。

   

    下面里一个建树的代码,可以手动模拟一下,便于理解:

   

typedef struct node  
{
	int weight;
	int parent;
	int lson;
	int rson;
}Htnode;

void creatHT(Htnode ht[], int n)
{
	for(int i = 0; i < 2 * n; i ++)
	{
		ht[i].parent = ht[i].lson = ht[i].rson = -1;
	}
	
	for(int i = n; i < 2 * n - 1; i ++)
	{
        int min1 = min2 = 9999;
        int lnode = rnode = -1;
        for(int j = 0; j < i; j ++)
        {
            if(ht[i].parent == -1)
            {
            	if(ht[j].weight < min1)
            	{
            		min2 = min1;
            		rnode = lnode;
            		min1 = ht[j].weight;
            		rnode = j;
            	}
            	else if(ht[j].weight < min2)
            	{
            		min2 = ht[j].weight;
            		rnode = j;
            	}
            }
            ht[i].weight = ht[lnode].weight + ht[rnode].weight;
            ht[i].lson = lnode;
            ht[i].rson = rnode;
            ht[lnode].parent = i;
            ht[rnode].parent = i;
        }
	}
}


  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值