哈夫曼树Huffman Tree详解与java实现

哈夫曼树(Huffman Tree)是一种带权路径长度最短的二叉树,也被称为最优二叉树。通过自底向上地将权重最小的两个结点配对构建,每次生成的新结点权值为两个子结点权值之和,最终形成具有最小带权路径长度的树。本文详细介绍了哈夫曼树的构造过程,并给出了Java实现的示例。
摘要由CSDN通过智能技术生成

树的一些基本概念

路径:在一棵树中,从一个结点到另一个结点所经过的所有结点,被我们称为两个结点间的路径。
路径长度:在一棵树中从一个结点到另一个结点所经过的“边”的数量为这两个结点之间的路径长度。
 结点的带权路径长度:树的每个结点都可以拥有自己的“权重”(weight)。结点的带权路径长度就是指树的根结点到该结点的路径长度,和该结点权重乘积
 树的带权路径长度:就是指一棵树中所有叶子结点的带权路径长度之和,也被简称为WPL
 示例:
 如下图二叉树中,从根节点A到叶子结点H的路径是A,B,D,H。
 共经历了三条边A->B,B->D,D->H,因此路径为3。
 如图示,结点H的权重是3,则结点H的带权路径长度是3X3 = 9。
 树的路径长度为 3X3 + 6X3 + 1X2 + 4X2 + 8X2 = 53 。
 示例二叉树

哈夫曼树

哈夫曼树简介

哈夫曼树(Huffman Tree)是在叶子结点和权重确定的情况下,带权路径长度最小的二叉树,也被称为最优二叉树
 举个例子,给定权重分别为1,3,4,6,8的叶子结点,应该怎么构建二叉树使得其带权路径长度(叶子节点的路径与权重乘积和)最小?
 原则上,让权重小的叶子节点路径长(远离树根),权重大的叶子结点路径短(靠近树根)。如下图,左侧的这棵树就是哈夫曼树,它的WPL是46,小于之前例子中的53。
 

注意:同样的叶子结点构成的哈夫曼树可能不止一棵,比如下面这几棵树都是哈夫曼树。哈夫曼树

构造哈夫曼树的通用方法

通用方法总结:将叶子节点的权重从小到大排列,因为越小路径要越长,那么我们就从权重小的结点开始,按照规则两两配对自底向上的开始构造一个二叉树。主要操作只有两步,① 选择当前权重最小的两个结点,生成新的父结点;② 不考虑这两个已配对的子节点,将父结点的权重(俩子结点之和)加入队列,再选出当前权重最小两个结点重复步骤一。具体可看下面例子。

 (给定结点和权重)示例:假设有6个叶子结点,权重依次是2,3,7,9,18,25,如何构建一颗哈夫曼树,也就是带权路径长度最小的树呢?

  1. 构建森林
    我们把每一个叶子结点,都当做一棵独立的树(只有根结点的树),这样就形成了一个森林。如下图,右侧是叶子结点的森林,左侧是一个辅助队列,按照权值从小到大存储了所有叶子结点。至于辅助队列的作用,我们后续将会看到。1
  2. 选择当前权重最小的两个结点,生成新的父结点
    借助辅助队列,我们可以找到权值最小的结点2和3,并根据这两个结点生成一个新的父结点,父节点的权值是这两个结点权值之和。2
  3. 从队列中移除上一步选择的两个最小结点,把新的父节点加入队列
    也就是从队列中删除2和3,插入5,并且仍然保持队列的升序:
    3
  4. 选择当前权值最小的两个结点,生成新的父结点
    这是对第二步的重复操作。当前队列中权值最小的结点是5和7,生成新的父结点权值是5+7=12:
    4
  5. 从队列中移除上一步选择的两个最小结点
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值