赫夫曼树(最优二叉树)

1. 简介

定义: 赫夫曼树是n个带权叶子结点构成的所有二叉树中,带权路径长度(WPL)最小的二叉树。

叶子结点的带权路径: 叶子结点权值*到根节点的路径长度(叶结点的层数)

树的带权路径长度WPL(weighted path length):树中所有叶子结点的带权路径长度之和。

举个栗子:

如上图:WPL=3*2+5*2+8*2+9*2=50

问题: 将以上由[3,5,8,9]为叶子节点二叉树变成一棵赫夫曼树(也需要3/5/8/9为叶子结点)

思考:从赫夫曼树的定义可知-需要WPL最小,所以我们要将权值小的叶子结点放在下面,大的放在上面

构造赫夫曼树的方法:

​ 令集合 T{3,5,8,9},

​ a. 选出权值最小的两个结点(即3和5) 作为左右子树构造新的树,

​ 将新结点的权值设置为左右两结点值之和,如下图

​ b.在集合中删除选出的两个结点值,增加新结点的值T{8,8,9}

​ c.重复以上步骤,直到最后集合中只剩下一个元素为止,最后得到以下的一棵树:

这样就构造出了一棵赫夫曼树,也就是我们的最优二叉树

2. 代码实现

结点类 Node.java

//赫夫曼树
public class Node implements Comparable<Node>{int value;Node left;Node right;public Node(int value) {this.value = value;}//重写方法-实现排序@Overridepublic int compareTo(Node o) {return this.value-o.value;}
}

赫夫曼树类:HuffmanTree.java

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;public class HuffmanTree {//测试赫夫曼树public static void main(String[] args) {int[] arr={3,5,8,9};Node huffmanTree = createHuffmanTree(arr);System.out.println("创建的赫夫曼树的头结点权值:"+huffmanTree.value);}//传入数组创建一个赫夫曼树,返回创建赫夫曼树的头结点public static Node createHuffmanTree(int[] arr){//将数组中的数据变成二叉树(只有一个结点),存到集合中List<Node> nodes = new ArrayList<>();for(int value:arr){nodes.add(new Node(value));}//循环,当集合中只有一个元素时,这个元素就是我们需要的赫夫曼树while(nodes.size()>1){//排序集合Collections.sort(nodes);//选出根节点权值最小的两颗树Node left=nodes.get(nodes.size()-1);Node right=nodes.get(nodes.size()-2);//将这两棵子树创建新的树,权值为子树之和Node parent = new Node(left.value + right.value);//将两个子树连接到新树上面parent.left=left;parent.right=right;//从集合中移除则两棵子树nodes.remove(left);nodes.remove(right);//增加新创建的树到集合nodes.add(parent);}//返回赫夫曼树头结点return nodes.get(0);}
}

结果:

创建的赫夫曼树的头结点权值:25

后面将介绍赫夫曼编码以及编码/解码还有用赫夫曼树进行文件压缩和解压

【赫夫曼树详解】赫夫曼树简介及java代码实现-数据结构07相关推荐

  1. 奇小葩讲设备树(3/5)-- Linux设备树详解(三)u-boot设备树的传递

    前面两节介绍了设备的基本概念.编译.结构的组成,本章讨论的主要内容为 dtb如何通过Bootloader引导程序加载到内核 bootloader如何解析dbt bootloader支持哪些dtb的操作 ...

  2. 数据结构图文解析之:哈夫曼树与哈夫曼编码详解及C++模板实现

    0. 数据结构图文解析系列 数据结构系列文章 数据结构图文解析之:数组.单链表.双链表介绍及C++模板实现 数据结构图文解析之:栈的简介及C++模板实现 数据结构图文解析之:队列详解与C++模板实现 ...

  3. c语言霍夫曼函数,使用C语言详解霍夫曼树数据结构

    1.基本概念 a.路径和路径长度 若在一棵树中存在着一个结点序列 k1,k2,--,kj, 使得 ki是ki+1 的双亲(1<=i 从 k1 到 kj 所经过的分支数称为这两点之间的路径长度,它 ...

  4. Trie树详解及其应用

    原文:http://blog.csdn.net/hackbuteer1/article/details/7964147 Trie树详解及其应用

  5. B-、B树详解及模拟实现

    B-.B树详解及模拟实现 文章目录 B-.B树详解及模拟实现 一.B-树 二.B树 1.性质 2.特性解释 3.B树的插入操作 4. B树的删除操作 5.B树摸拟实现 一.B-树 B-树就是B树 二. ...

  6. Android 驱动(12)---Linux DTS(Device Tree Source)设备树详解

    Linux DTS(Device Tree Source)设备树详解 Linux DTS(Device Tree Source)设备树详解之一(背景基础知识篇) Linux DTS(Device Tr ...

  7. 【学习笔记】线段树详解(全)

    [学习笔记]线段树详解(全) 和三个同学一起搞了接近两个月的线段树,头都要炸了T_T,趁心态尚未凉之前赶快把东西记下来... [目录] [基础]作者:\((Silent\)_\(EAG)\) [懒标记 ...

  8. Jmeter之查看结果树详解

    查看结果树详解 文章目录 查看结果树详解 前言 一.官网介绍 二.具体详解 1.左侧的结果列表 2.右侧的"取样器结果" 3.请求"选项卡 4."响应数据&qu ...

  9. 机器学习算法(二十五):KD树详解及KD树最近邻算法

    目录 1 KD树 1.1 什么是KD树 1.2 KD树的构建 1.3 KD树的插入 1.4 KD树的删除 1.5 KD树的最近邻搜索算法 1.5.1 举例:查询点(2.1,3.1) 1.5.2 举例: ...

最新文章

  1. NetBeans 时事通讯(刊号 # 103 - May 18, 2010)
  2. codeblock 带mingw的版本_云顶之弈10.22新版本最强阵容排名 10.22版本吃鸡阵容推荐...
  3. tpcc mysql优化_tpcc_mysql性能测试
  4. 【实习之T100开发】Linux 学习笔记
  5. ARM处理器系统初始化编程注意事项
  6. RIP/EIGRP/OSPF/ISIS使用的端口号/协议号
  7. Ubuntu20.04系统联网
  8. Google OpenThread 技术研讨会
  9. android数据线接口定义,安卓手机数据线接口类型
  10. java 串口 中文乱码_Java 实现 POS 打印机无驱串口打印(解决中文乱码)
  11. [Caffe]: HDF5Data Layer
  12. 在Firefox中以电影院风格观看YouTube视频
  13. mac book pro 最全快捷键
  14. Android安全:onCreate()函数的Native化
  15. 淘宝号标签,,猜你喜欢推荐,消费潜力值,淘宝号的千人千面,购物足迹,潜在购买类目,淘宝号的潜在成交词,官方推荐的搜索词,淘宝标签查询,淘宝号是否打上标签,标签透视,标签接口,猜你喜欢接口,
  16. CUMT2021一道SSRF
  17. imx6q项目:使用psplash制作开机动画
  18. 日语网站的服务器迁移,云端服务器日语是什么
  19. iOS备忘录之XCode插件
  20. 数据挖掘实战分享:财政收入影响因素分析及预测(二)

热门文章

  1. sql IFNULL
  2. sql 数组三 展平数组
  3. java floatmath_【Android】解决FloatMath类中方法在API 23以后不存在问题
  4. 组态王怎么做超级曲线_鱼怎么做才好吃?试试这个方法,吃着过瘾,还超级下饭!(收藏)...
  5. 162. Leetcode 45. 跳跃游戏 II (贪心算法-贪心区间)
  6. 31. Leetcode 82. 删除排序链表中的重复元素 II (链表-双指针)
  7. 数据挖掘流程(三):特征工程
  8. Python输出py文件模拟代码高亮
  9. java messagebox 关闭_wince/WinForm下实现一个自动关闭的MessageBox
  10. 虚拟机安装多了,怎么删除?