手记

【金秋打卡】第13天 JavaScript版数据结构与算法-树形结构概念(哈夫曼)

课程名称: JavaScript版数据结构与算法
课程章节:第8章 数据结构之“树”
课程讲师: lewis
课程内容:前端JS的算法基础
课程介绍:
8-1 树简介
8-2 深度与广度优先遍历
8-3 二叉树的先中后序遍历
8-4 二叉树的先中后序遍历(非递归版)
8-5 LeetCode:104. 二叉树的最大深度
8-6 LeetCode:111. 二叉树的最小深度
8-7 LeetCode:102. 二叉树的层序遍历
8-8 LeetCode:94. 二叉树的中序遍历
8-9 LeetCode:112. 路径总和
8-10 前端与树:遍历 JSON 的所有节点值


一、 树的典型案例哈夫曼树

在数据结构理论中,哈夫曼树又称为最优树,相关的知识点还有哈弗曼编码等。


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

(1)节点路径

按照规定,将树中一个节点到另一个节点所经历的分支,称为节点路径,比如上图中节点A到节点E的路径为ABE。

(2)路径长度

根据上述“节点路径”的定义,将路径上的分支总数称为路径长度,比如上图中节点A到节点E的路径长度为2。

(3)节点的带权路径长度

根据上述“节点路径”和“路径长度”的定义,将从根节点到某节点的路径长度和节点权值的乘积,称为节点的带权路径长度。比如上图中节点A到节点D的路径长度为2,权值为8,则带权路径长度为2x8=16。

(4)树的带权路径长度

根据上述“节点的带权路径长度”的定义,将树中所有叶子节点的带权路径长度,称为树的带权路径长度。比如上图中,三个叶子节点C、D、E,对应的路径长度分别为1、2、2,对应的权值分别为4、8、3,则树的带权路径长度为:

将上述概念形式化,可以使用下面的公式进行计算:

其中了表示路径长度,w表示权值,n表示叶子节点个数。

举个例子:
哈夫曼树能够根据节点的查找频率来构造更有效的搜索树,是 WPL 最小的树。

哈夫曼树的构造可以理解为将权值最小的两棵二叉树合并,这个树的权值等于 2 个子树的和。

关于如何选取两个权值最小的二叉树,可以使用最小堆实现,复杂度是 O(N log N)。

比如权值:{1,2,3,4,5},可以得出:

计算以下 WPL = 2 * 3 + 2 * 4 + 2 * 5 + 3 * 1 + 3 * 2 = 33

哈夫曼树的特点:

没有度为 1 的节点(即不存在只有一个子节点的节点)
n 个叶子节点的哈夫曼树,总节点数为 2n-1
n0:叶节点总数
n1:只有一个子节点的节点总数
n2:有两个子节点的节点总数
那么 n2 = n0 - 1
由于没有度为 1 的节点,所以其总节点数为 n + n - 1 = 2n-1
哈夫曼树任意非叶节点的左右子树交换后仍是哈夫曼树
对同一权值{W1,W2,W3,…,Wn},允许存在不同构造的两颗哈夫曼树

哈夫曼编码用于数据存储中做压缩,如下案例:
问题:
给定一段包含 50 个字符的字符串,由 {a,b,c,d,e,f}构成,且每个字符出现次数不同,会有如下几种存储方式。
分析
等长 ASCII 编码,存储长度为 50 * 8 = 400 位
等长 3 位编码,存储长度为 50 * 3 = 150 位
不等长编码,出现频率高的字符编码短些,出现频率低的字符编码长些。
第三种便可以使用哈夫曼树来实现,假如给定:

字符 a b c d e f
次数 18 4 16 1 1 10

构成哈夫曼树:

`

``

所以: a:0; b:1101; c:10; d:11000; e:11001; f:111 。

长度为: 1 * 18 + 4 * 4 + 16 * 2 + 1 * 5 + 1 * 5 + 10 * 3 = 106 字符。


总结

今天我们首先明白树形结构,并且通过哈夫曼树来了解推导方案,树的遍历方法这些在下一个章节结合实际来进行阐述。

之前在学习的过程中,忽略了问答区的一些经典问题,研究一下确实有些东西可以更好的补充我们的知识体系,建议大家也可以广泛参与,形成知识的反馈闭环,效果更佳。

0人推荐
随时随地看视频
慕课网APP