哈夫曼树

一、哈夫曼树概述

1.1 什么是哈夫曼树

给定 n 个权值作为 n 个叶子节点,构造一棵二叉树,若该树的带权路径长度(Weighted Path Length of Tree)达到最小, 称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree)。

哈夫曼树是带权路径长度最短的树,权值较大的节点离根较近。

1.2 哈夫曼树重要概念

路径和路径长度

在一棵树中,从一个节点往下可以到达孩子或孙子节点的通路,称为路径。

通路中分支的数目称为路径长度。若规定根节点的层数为 1,则从根节点到第 L 层节点的路径长度为 L-1。

节点的权及带权路径长度

若给树中节点赋予一个有着某种含义的数值,则这个数值称为该节点的权。

节点的带权路径长度为:从根节点到该节点之间的路径长度与该节点的权的乘积。

树的带权路径长度

树的带权路径长度规定为所有叶子节点的带权路径长度之和,记为 WPL(Weighted Path Length of Tree)。权值越大的节点离根节点越近的二叉树才是最优二叉树。

直接看概念,可能有一点抽象。如下图所示,是同一序列构成的不同二叉树的三种情况:

在这里插入图片描述

其中 WPL 最小的就是最优二叉树,即第二个是最优二叉树。

二、哈夫曼树的创建思路

给定一个序列,创建哈夫曼树的基本思路如下:

  1. 将序列从小到大进行排序;
  2. 将每一个数据看作是一个节点,每个节点可以看成是一颗最简单的二叉树;
  3. 取出根节点权值最小的两颗二叉树组成(权值较小的作为左节点,较大的作为右节点)一颗新的二叉树,该新的二叉树的根节点的权值是前面两颗二叉树根节点权值的和;
  4. 在原序列中将步骤 3 取出的两个根节点移除,然后将它们组成的新的二叉树的根节点放入到原序列中;
  5. 不断重复 1-2-3-4 的步骤,直到序列中只剩下一个节点,该节点就是哈夫曼树的根节点。

【图解分析】

下面将以序列 {13, 7, 8, 3} 为例,图解创建哈夫曼树的过程。

  1. 首先,序列升序排序得到 {3, 7, 8, 13}。

  2. 把每个数据看做是一个节点,取出节点权值最小的两个节点 3, 7 组成一颗新的二叉树,该二叉树权值为 3+7 = 10。

    在这里插入图片描述

  3. 在原序列中将第 2 步取出的两个权值最小的移除,然后将第 2 步生成的新节点的权值加入到原序列中,并重新排序。

    在这里插入图片描述

  4. 再次取出权值最小的两个节点 8, 10 组成一颗新的二叉树,新的二叉树权值为 8+10 = 18。然后从序列中移除节点 8,10,将 18 添加进去,然后重新排序。

    在这里插入图片描述

  5. 再次取出权值最小的两个节点 13,18 组成一颗新的二叉树,新的二叉树权值为 13+18 = 31。然后从序列中移除 13, 18,将 31 添加进去。此时序列中只剩下一个节点,该节点即为哈夫曼树的根节点。

    在这里插入图片描述

至此,序列 {13, 7, 8, 3} 的哈夫曼树创建完毕。

三、哈夫曼树的代码实现

哈夫曼树的完整代码实现如下:

/**
 * @Description 哈夫曼树
 */
public class
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值