有几章内容在做个人网站同步是丢掉了,😒
知识点
[记录本章包含哪些内容]
未攻克
#todo线索二叉树
笔记
大纲要求
-
树的基本概念
-
二叉树
- 二叉树定义及其主要特征;
- 二叉树的顺序存储结构和链式存储结构;
- 二叉树的遍历;
- 线索二叉树的基本概念和构造
-
树、森林
- 树的存储结构;
- 森林与二叉树的转换
- 树和森林的遍历
-
树和二叉树的应用
- 哈夫曼树和哈夫曼编码
- 并查集及其应用
-
考察形式:多以选择题或综合题考察,树遍历相关算法题。树和二叉树的性质、遍历操作、转换、存储结构和操作特性等。满二叉树、完全二叉树、线索二叉树、哈夫曼树的定义和性质(选择题必涉及)
树
树的基本概念
- 当 n=0 时,称为空树
title: 在任意一颗非空树应满足
- 有且仅有一个特定的称为根的结点
- 当n>1时,其余结点可分为m(m>0)个互不相交的有限集$T_1,T_2,...,T_m$,其中每个集合本身又是一棵树,并且称为根的子树
1.树的定义是递归的,即在树的定义中又用到了其自身,树是一种递归的数据结。树作为一种逻辑结构,同时也是一种分层结构,具有以下两个特点:
- 树的根节点没有前驱,除根节点外的所有结点有且只有一个前驱
- 树中所有结点都可以有 0 个或多个后继
- 树适用于表示具有层次结构的数据。树中的某个结点(除根结点外)最多只和上一层的一个结点(即其父结点)有直接关系,树结点没有直接上层结点,因此在 n 个结点的树中有 n-1 条边。而树中每个结点与其下一层的 0 个或多个结点(即其孩子结点)都有直接关系
- 结点的度和树的度:结点度是看该结点有几个孩子,有几个则度是几,树的度则是结点谁有孩子最多,这个最多树就是树的度,比如根节点有好几个节点,每个节点的孩子数不同,看谁的孩子数多,就是树的度
- 分支节点也叫非终端节点,在分支结点中,每个结点的分支树就是该结点的度
- 度为 0 的节点称为叶节点(没有孩子结点),也叫终端节点
结点的深度、高度和层次
- 结点的层次从树根开始定义,根节点为第 1 层,它的孩子为第 2 层,以此类推。
- 结点的深度就是结点所在的层次
- 树的高度(或深度)是树中结点的最大层数
- 结点的高度是以该结点为根的子树的高度
- 路径和路径长度:树中两个结点之间的路径是由这两个结点之间所经过的结点序列构成的,而路径长度是路径上所经过的边的个数;树的路径长度是指树根到每个结点的路径长的总和,根到每个结点的路径长度的最大值应是树的高度减 1
【注🧨】因为树中的分支是有向的,即从双亲指向孩子,所以树中的路径是从上向下的,同一双亲的两个孩子之间不存在路径
小节选择题答案
序号 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|---|
答案 | D | C | A | A | B | B | D |
错题解析
- A
- 【结论🧨】除根结点外,其它每个结点都是某个结点的孩子,因此树中所有结点的度数加 1 等于结点数,也即所有结点的度数之和等于总结点数减 1
- A
- 要使得度为 4、高度为 h 的树的总结点数最少,需要满足以下两个条件:
①至少有一个结点有 4 个分支
②每层的结点数目尽可能少
如图:结点个数为 h+3
- 要使度为 4,高度为 h 的树的总结点数最多,应使每个非叶结点的度均为 4,即为满树,总结点个数最多为 1 + 4 + 4 2 + . . . + 4 h − 1 1+4+4^2+...+4^{h-1} 1+4+42+...+4h−1
- C
- 要求满足条件的数,那么该树是一颗完全三叉树。
- 在度为 3 的完全三叉树中,第 1 层有 1 个结点,第 2 层有 3 1 = 3 3^1=3 31=3 个结点,第 3 层有 3 2 = 9 3^2=9 32=9 个结点,第 4 层有 3 3 = 27 3^3=27 33=27 个结点,因此结点数之和为 1+3+9+27=40,第 5 层的结点数=50-40=10 个,因此最小高度为 5
- B
- 总结点数 n = n 0 + n 1 + n 2 + n 3 = 6 + n 1 + 1 + 2 = 9 + n 1 n=n_0+n_1+n_2+n_3=6+n_1+1+2=9+n_1 n=n0+n1+n2+n3=6+n1+1+2=9+n1
- 总度数 = n − 1 = n 1 + 2 n 2 + 3 n 3 = n 1 + 2 + 6 = n 1 + 8 =n-1=n_1+2 n_2+3 n_3=n_1+2+6=n_1+8 =n−1=n1+2n2+3n3=n1+2+6=n1+8
- 根据题目条件无法得出
n
1
n_1
n1 的具体值,只能证明
n
1
n_1
n1 是一个大于或等于 9 的任意整数
- D
- 设叶结点数为 N 0 N_0 N0,总结点数为 N N N,则 N = N 1 + 2 N 2 + 3 N 3 + . . . + m N m + 1 N=N_1+2N_2+3N_3+...+mN_m+1 N=N1+2N2+3N3+...+mNm+1, 又因为 N = N 0 + N 1 + N 2 + N 3 + . . . + N m N=N_0+N_1+N_2+N_3+...+N_m N=N0+N1+N2+N3+...+Nm
- 所有 N 0 = N 2 + 2 N 3 + . . . + ( m − 1 ) N m + 1 = = ∑ i = 2 m ( i − 1 ) N i + 1 N_0=N_2+2N_3+...+(m-1)N_m+1 = =\sum_{i=2}^{m}(i-1) N_{i}+1 N0=N2+2N3+...+(m−1)Nm+1==∑i=2m(i−1)Ni+1
【注🧨】计算叶结点和总结点数:(利用两条性质)
- 树中的结点数等于所有结点的度数之和加 1
- 结点表示个数,n 为总结点个数,
n
i
n_i
ni 为度为
i
(
0
≤
i
≤
m
)
i(0≤i≤m)
i(0≤i≤m) 的结点个数,则
n
=
n
0
+
n
1
+
.
.
.
+
n
m
n=n_0+n_1+...+n_m
n=n0+n1+...+nm
- B
- 从结点自身: n = 20 + 10 + 1 + 10 + n 0 n=20+10+1+10+n_0 n=20+10+1+10+n0
- 从结点孩子: n = 20 ∗ 4 + 10 ∗ 3 + 1 ∗ 2 + 10 ∗ 1 + 1 n=20*4+10*3+1*2+10*1+1 n=20∗4+10∗3+1∗2+10∗1+1
- 联立解得: 41 + n 0 = 123 41+n_0=123 41+n0=123, n 0 = 82 n_0=82 n0=82
- C
【注🧨】树性质:即在 n 个结点的树中有 n − 1 n-1 n−1 条边
- 对于每棵树,结点要比边数多 1,
- 题中结点比边数一共多 10,则显然有 10 棵树
二叉树
强烈安利参考阅读、笔记 笔记 2
【注:符号说明🔣】[]该符号是向下取整
二叉树的基本概念
- 二叉树中不存在度大于 2 的结点
- 二叉树有左右之分,其次序不能任意颠倒
- 即使树中结点只有一颗子树,也要区分它是左子树还是右子树
二叉树与度为 2 的有序树的区别
①度为 2 的树至少有 3 个结点,而二叉树可以为空
②度为 2 的有序树的孩子的左右次序是相对于另一个孩子而言的,若某个结点只有一个孩子,则这个孩子就无须区分其左右次序,而二叉树无论其孩子数是否为 2,均需确定其左右次序,即二叉树的结点次序不是相对于另一结点而言的,而是确定的
几种特殊的二叉树
满二叉树:
- 二叉树中的每层都含有最多的结点。满二叉树的叶结点都集中在二叉树的最下一层,并且除叶结点之外的每个结点度数均为 2
- 对满二叉树按层序编号:约定编号从根结点(根结点编号为 1)起,自上而下,自左向右。这样,每个结点对应一个编号,对于编号为 i i i 的结点,若有双亲,则其双亲为「i/2」; 若有左孩子,则左孩子为 2 i;若有右孩子,则右孩子为 2 i+1
完全二叉树
- 高度为 h、有 n 个结点的二叉树,当且仅当其每个结点都与高度为 h 的满二叉树中编号为 1~n 的结点一一对应时,称为完全二叉树
二叉排序树
- 左子树和右子树又各是一棵二叉排序树
平衡二叉树
- (书) 树中任意一个结点的左子树和右子树的高度之差的绝对值不超过 1
正则二叉树
- 树中每个分支结点都有 2 个孩子,即树中只有度为 0 或 2 的结点
二叉树的性质
- 终端结点数就是叶结点数
- 非空二叉树上的叶结点数等于度为 2 的结点数+1,即 n 0 = n 2 + 1 n_0=n_2+1 n0=n2+1
设 B 为分支总数,结点总数 n=B+1, B= n 1 + 2 n 2 n_1+2n_2 n1+2n2 = 总结点数-1, n 1 n_1 n1 是度为 1 的结点总数, n 2 n_2 n2 是度为 2 的结点总数,
- 非空二叉树的第 k 层最多有 2 k − 1 2^{k-1} 2k−1 个结点( k ≥ 1 k≥1 k≥1)
- 高度为 h 的二叉树至多有 2 h − 1 2^h-1 2h−1 个结点( k ≥ 1 k≥1 k≥1)
- m 叉树的第 k 层最多有 m k − 1 m^{k-1} mk−1 个结点,高度为 h 的 m 叉树至多有 ( 2 h − 1 ) ( m − 1 ) (2^h-1)(m-1) (2h−1)(m−1) 个结点
【注🧨编号】 对完全二叉树按从上到下,从左到右的顺序依次编号 1,2,… ,n,有以下关系:
①若 i ≤ [ n / 2 ] i≤[n/2] i≤[n/2],则结点 i 为分支结点,否则为叶结点,即最后一个分支结点的编号为[n/2]
②叶结点只可能在层次最大的两层上出现(若删除满二叉树中最底层、最右边的连续 2 个或以上的叶结点,则倒数第二层将会出现叶结点)
③若有度为 1 的结点,则只可能有一个,且该结点只有左孩子而无右孩子(度为 1 的分支结点只可能是最后一个分支结点,其结点编号为[n/2])
④按层序编号后,一旦出现某结点(如结点 i)为叶结点或只有左孩子的情况,则编号大于 i 的结点均为叶结点(与结论①和结论③是相通的)
⑤若 n 为奇数,则每个分支结点都有左、右孩子;若 n 为偶数,则编号最大的分支结点(编号为 n/2)只有左孩子,没有右孩子,其余分支结点都有左、右孩子
⑥当 i > 1 i>1 i>1 时,结点 i 的双亲结点的编号为[i/2]
⑦若结点 i 有左、右孩子,则左孩子编号为 2 i 2i 2i,右孩子编号为 2 i + 1 2i+1 2i+1
⑧结点 i 所在层次(深度)为 [ l o g 2 i ] + 1 [log_2 i]+1 [log2i]+1
- 具有 n 个(n>0)结点的完全二叉树的高度为
l
o
g
2
(
n
+
1
)
log_2(n+1)
log2(n+1) 或
l
o
g
2
n
+
1
log_2 n+1
log2n+1
二叉树的存储结构
顺序存储结构
建议从数组下标 1 开始存储树中的结点,保证数组下标和结点编号一致
- 存储方式:用一组连续的存储单元依次自上而下、自左至右存取完全二叉树上的结点元素,即将完全二叉树上编号为 i 的结点元素存储在一维数组下标为 i-1 的分量中
- 适用于完全二叉树和满二叉树,树中结点的序号可以唯一的反映结点之间的逻辑关系,这样既能最大可能的节省存储空间,又能利用数组元素的下标值确定结点在二叉树中的位置,以及结点之间的关系
- 存储弊端(空间利用率低):为了让数组下标能反映二叉树中结点之间的逻辑关系,只能添加一些并不存在的空结点,让其每个结点与完全二叉树上的结点相对照,再存储到一维数组的相应分享中。最坏情况下,高度为 h 且只有 h 个结点的单支树需要占
2
h
−
1
2^h -1
2h−1 个存储单元,用 0 表示并不存在的空结点
链式存储结构
【✨主要结论✨】在含有 n 个结点的二叉树链表中,含有 n+1 个空链域
小节选择题答案
题型总结
操作步骤
- 看树是什么树,常考完全二叉树,三叉树,满二叉树(借助完全二叉树考)、三叉树
类型 1:树为二叉树,已知叶结点树、求总结点数
类型 2:树为二叉树,已知结点树、求叶结点数
二叉树的遍历和线索二叉树
二叉树的遍历
- 二叉树的遍历是指按某条搜索路径访问树中每个结点,使得每个结点均被访问一次,而且仅被访问一次
- 二叉树是一种非线性结构,每个结点都有可能有两颗子树,因此需要寻找一种规律,以便使二叉树上的结点能排列在一个线性队列上,进而便于遍历
- 由二叉树的递归定义可知,遍历一颗二叉树便要决定对根结点 N、左子树 L 和右子树 R 的访问顺序。按照先遍历左子树再遍历右子树的原则,常见的遍历次序有先序(NLR)、中序(LNR)和后序(LRN)三种遍历算法,其中"序"指的是根结点在何时被访问
- 三种算法中,递归遍历左、右子树的顺序都是固定的,只是访问根结点的顺序不同
- 三种算法中,每个结点都访问一次且仅访问一次,所以时间复杂度都为 O ( n ) O(n) O(n)
- 递归遍历中,递归工作栈的栈深恰好为树的深度,所以在最坏情况下,二叉树是有 n n n 个结点且深度为 n n n 的单支树,遍历算法的空间复杂度为 O ( n ) O(n) O(n)
二叉树遍历-先序遍历(NLR)
- 缩写:PreOrder
- 若二叉树为空,则什么都不做;否则:
- ①访问根结点
- ②先序遍历左子树
- ③先序遍历右子树
ID: ID_4qby
Number of Columns: 2
Largest Column: standard
border: off
二叉树遍历-中序遍历 (LNR)
- 缩写:InOrder
- 若二叉树为空,则什么都不做;否则:
- ①中序遍历左子树
- ②访问根结点
- ③中序遍历右子树
ID: ID_3mt2
Number of Columns: 2
Largest Column: standard
二叉树遍历-后序遍历 (LRN)
- 缩写:PostOrder
- 若二叉树为空,则什么也不做;否则:
- ①后序遍历左子树
- ②后续遍历右子树
- ③访问根结点
ID: ID_nzu9
Number of Columns: 2
Largest Column: standard
二叉树遍历-层次遍历
- 层次遍历,自上而下,从左至右,对二叉树中的各个结点进行逐层访问
- 进行层次遍历,需要借助一个队列
- 层次遍历思想:
- ①首先将二叉树的根结点入队
- ②若队列非空,则队头结点出队,访问该结点,若它有左孩子,则将其左孩子入队;若它有右孩子,则将其右孩子入队
- ③重复第②步,直至队列为空
ID: ID_3u2i
Number of Columns: 2
Largest Column: standard
— column-end —
— end-multi-column
由遍历序列构造二叉树
先序序列和中序序列构造二叉树
- 先序序列中,第一个结点为二叉树的根结点
- 中序序列中,根结点必然将中序序列分割为两个子序列,前一个子序列是根的左子树的中序序列,后一个子序列是根的右子树的中序列。左子树的中序序列和先序序列的长度相等,右子树的中序序列和先序序列的长度相等
- 根据这两个子序列,可以在先序序列中做到左子树的先序序列和右子树的先序序列
- 示例:
后序序列和中序序列构造二叉树
- 后序序列中,最后一个结点为二叉树的根结点
- 中序序列中,根结点必然将中序序列分为两个子序列,方法同上
- 示例:后续序列 (CBEHGIFDA)和中序序列(BCAEDGHFI)所确定的二叉树
层序序列和中序序列构造二叉树
- 层次遍历中,第一个结点为二叉树根结点
【注🧨】先序序列、后序序列和层序序列的两两组合,无法唯一确定一颗二叉树
线索二叉树
-
遍历二叉树是以一定的规则将二叉树中的结点排列成一个线性序列,从而得到几种遍历序列,使得该序列中的每个结点(第一个和最后一个除外)都有一个直接前驱和直接后继
【规定💡】若无左子树,令 lchild 指向其前驱结点;若无右子树,令 rchild 指向其后继结点
-
以结点结构构成的二叉链表作为二叉树的存储结构,称为线索链表。其中指向结点前驱和后继的指针称为线索
-
加上线索的二叉树称为线索二叉树
中序线索二叉树的构造
- 二叉树的线索化是将二叉链表中的空指针改为指向前驱或后继的线索
- 而前驱或后继的信息只有在遍历时才能得到,因此线索化的实质是遍历一次二叉树
#TODO细节待补充
小节选择题答案
序号 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
答案 | C | D | D | C | C | B | C | D | B | D | A | D | A | D | |
序号 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 |
答案 | A | D | A | B | B | A | C | C | D | C | D | D | C | ||
序号 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | ||
答案 | D | D | D | A | D | A | B | A |
错题解析
-
C #todo答案未理解
-
C
#Tips 画图
- 中序遍历时,先访问左子树,再访问根结点,后访问右子树。
- N 在 m 前的 3 种可能性如下图,由图看出 n 总是在 m 的左方
- B
- 结点 v 的编号比其左子树上的最小编号还小,而 v 的右子树中的最小编号大于 v 的左子树中的最大编号,因此 v 的编号比其左右子树上的所有编号都小,是按照先序遍历次序
- D
- 前序为 A、B、C 的不同二叉树有 5 种,其中后序为 C、B、A 的有 4 种(前 4 种),都是单支树
- C
- 7 个结点的完全二叉树是一颗 3 层的满二叉树,画出相应二叉树的树形,根据后序遍历序列填入相应的结点,得到相应的完全二叉树,求得其先序遍历序列为 ABCDEFG
- C
- 二叉树的前序遍历为 NLR,后序遍历为 LRN
- 题意:先序遍历 X 在 Y 前,后序 X 在 Y 后,若设 X 在根位置,Y 在其左子树或右子树中,满足要求
- C==(图(b)也叫 b 在 a 的左子树吗?)==
-
先序序列是…a…b…,因此 a 和 b 结点的 3 种情况如图 (a)~©
-
中序序列是…b…a…,因此 a 和 b 结点的 3 种情况如图 (d)~(f)
-
相同部分是 b 在 a 的左子树中
- B
- 由先序序列知 1 为根结点,2 是 1 的孩子
- A 选项 3 是 1 的左孩子,对应前序序列应为 13…
- C 选项 4 是 1 的左孩子,对应先序序列应为 14…
- D 选项 463572 为 1 的右子树,前序中 4 和 6 应该相连,5,7 应相连
- B
- 中序遍历是“左根右”,后序遍历是“左右根”
- 当任一结点没有右子树时,两种遍历都是“左根”
- 当二叉树为空树或只有根结点时,其中序序列和后序序列也相同
【注🧨】要想二叉树的中序序列和后序序列相同,该二叉树只有根结点或为空树或任一结点均无右子树时满足
-
B (感觉答案有误C、D)
-
C
- 删除一个结点时,需要先递归删除它的左右孩子,并释放它们所占的存储空间,然后删除该结点,并删除它所占的存储空间,与后序遍历的访问顺序相吻合
-
C
【注🧨】线索二叉树中用 ltag/rtag 标识结点的左/右指针域是否为线索,其值为 1 时,对应指针域为线索,其值为 0 时,对应指针域为左/右孩子 -
D
- 对左子树为空的二叉树进行先序线索化,根结点的左子树为空且没有前驱结点(先遍历根结点)(第一个)
- 先序遍历的最后一个元素为叶结点,左、右子树均为空且有前驱无后继结点(第二个)
- 所以线索化后,树中空链域有 2 个
- A
- 在二叉树的后序遍历中,叶结点 X 的后继是其双亲,所以 X 的右线索应指向该结点
-
C
-
B
- 先序是根左右
- 后序是左右根(相反)—根右左
- 所以二叉树的形态要不是没左要不就是没右,为单支树
- D
- 后序结果为 dbca
- 结点d左边为空,故无前驱,为 NULL,排除 BC
- 结点 d 的后继为 b,应该指向 b 而不是 c,故,排除 A
- C
- 根据先序序列和后序序列是得不到确定的中序序列的
- 知先序和中序可求得后序(结合选项看)
- A
- 原题根结点的孩子结点也就是说第二层
- A(同 30 题)
- D
- 中序线索化结果:debXac
- 左线索为 b,右线索为a
-
B
-
B
- B
- 先序:根左右
- 中序:左根右
- 当左没有的时候是相同的
42
树、森林
树的存储结构
- 树可采用顺序存储结构或采用链式存储结构
- 任何存储结构都要求能唯一的反映各结点之间的逻辑关系
- [>] 双亲表示法:根结点下标为 0,其伪指针域为-1
- 双亲表示法利用了每个结点(根结点除外)只有唯一双亲的性质,可以很快得到每个结点的双亲结点,但求结点的孩子时则需要遍历整个结构
【注🧨】区别树的顺序存储结构与二叉树的顺序存储结构
- 在树的顺序存储结构中,数组下标代表结点的编号,下标中所存的内容指示了结点之间的关系
- 在二叉树的顺序存储结构中,数组下标既代表了结点的编号,又指示了二叉树中各结点之间的关系
- 二叉树属于树,因此,二叉树也可用树的存储结构来存储,但树却不能用二叉树的存储结构来存储
-
[>] 孩子表示法
将每个结点的孩子结点视为一个线性表,且以单链表作为存储结构,则 n 个结点就有 n 个孩子链表(叶结点的孩子链表为空表)。
而 n 个头指针又组成一个线性表,为便于查找,可采用顺序存储结构 -
与双亲表示法相反,孩子表示法寻找孩子的操作非常方便,而寻找双亲的操作则需要遍历 n 个结点中孩子链表指针域所指向的 n 个孩子链表
-
[>] 孩子兄弟表示法
-
孩子兄弟表示法又称二叉树表示法,即以二叉树作为树的存储结构
-
孩子兄弟表示法使每个结点包括三部分内容:结点值、指向结点第一个孩子结点的指针,以及指向结点下一个兄弟结点的指针(沿此域可以找到结点的所有兄弟结点)
【注🧨】孩子兄弟表示法比较灵活,其最大的①优点是可以方便的实现树转换为二叉树的操作,易于查找结点的孩子等,②缺点是从当前结点查找其双亲结点比较麻烦。③若为每个结点增设一个 parent 域指向其父结点,则查找结点的父结点也会比较方便
树、森林与二叉树的转换
-
二叉树和树都可以用二叉链表作为存储结构
-
从物理结构上看,树的孩子兄弟表示法与二叉树的二叉链表表示法是相同的,因此可以用同一存储结构的不同解释将一棵树转换为二叉树
-
[>] 树转换为二叉树
-
规则:每个结点的左指针指向它的第一个孩子,右指针指向它在树中的相邻右兄弟,称为"左孩子右兄弟",由于根结点没有兄弟,因此树转换得到的二叉树没有右子树
-
树–>二叉树画法:
①在兄弟结点之间加一连线
②对每个结点,只保留它与第一个孩子的连线,而与其它孩子的连线全部抹掉
③以树根为轴心,顺时针旋转 45°
-
[>] 森林转换为二叉树
-
规则:先将森林中的每棵树转换为二叉树,由于任意一棵树对应的二叉树的右子树必空,若把森林中第二颗树根视为第一棵树根的右兄弟,即将第二棵树对应的二叉树当作第一棵二叉树根的右子树,将第三棵树对应的二叉树当作第二棵二叉树根的右子树,依次类推
-
森林–>二叉树的画法:
①将森林中的每棵树转换为相应的二叉树
②每棵树的根也可视为兄弟关系,在每棵树的根之间加一根连线
③以第一棵树的根为轴心顺时针旋转 45° -
[>] 二叉树转换为森林
-
规则:若二叉树非空,则二叉树的根及其左子树为第一棵树的二叉树形式,所以将根的右链断开。二叉树根的右子树又可视为一个由除第一棵树外的森林转换后的二叉树,应用同样的方法,直至最后只剩一颗没有右子树的二叉树为止,最后将每棵二叉树依次转换成树,就得到了原森林
【注🧨】二叉树转换为树或森林是唯一的
树和森林的遍历
-
[>] 树的遍历:树也有层次遍历,与二叉树的层次遍历思想基本相同,即按层序依次访问各结点
-
[>] 森林的遍历:①先访问森林中第一棵树的根结点,②先序遍历第一棵树中根结点的子树森林,③先序遍历除去第一棵树之后剩余的树构成的森林
小结选择题答案
序号 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
答案 | A | C | C | C | |||||||||||
序号 | 16 | 17 | 18 | 19 | |||||||||||
答案 | C | ||||||||||||||
- 树的棵树:画出图后,沿最右边砍断/
- 结点最多的树的结点数:结点最多的树一定是左子树,数就 ok
- B
- 树的叶子结点数跟左为空的指针域数目保持一致,比右指针域为空的数据+1
- B
- 同 9 题
- 中序遍历
树与二叉树的应用
- [>] 定义
- 从树中一个结点到另一个结点之间的分支构成这两个结点之间的路径
- 路径上的分支数目称为路径长度
- 在许多应用中,树中结点常常被赋予一个表示某种意义的数值,这个值称为该结点的权
- 从树的根到一个结点的路径长度与该结点上权值的乘积,称为该结点的带权路径长度,树中所有叶结点的带权长度之和称为该树的带权路径长度,记为 WPL
- 在含有 n 个带权叶结点的二叉树中,其中带权路径长度(WPL)最小的二叉树称为哈夫曼树,也叫最优二叉树
-
[>] 哈夫曼编码
-
在数据通信中,若对每个字符用相等长度的二进制位表示,称这种编码方式位固定长度编码; 若允许对不同字符用不等长的二进制位表示,则这种编码方式称为可变长度编码
-
可变长度编码比固定长度编码好的地方在对频率高的字符赋以短编码,而对频率较低的字符赋以较长一些的编码,从而可以使字符的平均编码长度减短,起到压缩数据的效果
-
前缀编码:若没有一个编码是另一个编码的前缀,则称这样的编码为前缀编码,可唯一翻译字符
-
二叉树设计二进制前缀编码:叶结点分别表示 X 字符,约定左分支表示 0,右分支表示 1,从根到叶结点的路径上用分支标记组成的序列作为该叶结点字符的编码,(可以证明如此得到的必为前缀编码),如例:
-
哈夫曼编码是一种非常有效的数据压缩编码
-
[i] 哈夫曼树–>哈夫曼编码
- 将每个字符当作一个独立的结点,其权值为它出现的频度(次数),构造出对应的哈夫曼树
- 将从根到叶结点的路径上分支标记的字符串作为该字符的编码
【注🍓】左分支和右分支究竟是表示 0 还是表示 1 没有明确规定,因此构造出的哈夫曼树并不唯一,但各哈夫曼树的带权路径长度 WPL 相同且为最优,此外,如有若干权值相同的结点,则构造出的哈夫曼树更可能不同,但 WPL 必然相同且为最优
-
[>] 并查集
-
并查集是一种简单的集合表示,支持 3 种操作
-
[i] 并查集存储结构
规则:(每个子集合是一棵树,所有表示子集合的树,构成表示全集合的森林,存放在双亲表示数组内)
- 通常用数组元素的下标代表元素名,用根结点的下标表示子集合名,根结点的双亲域为负数(可设置为该子集合元素数量的相反数)
为了得到两个子集合的并,只需要将其中一个子集合根结点的双亲指针指向另一个集合的根结点(操作:Union)
-
在采用树的双亲指针数组表示作为并查集的存储表示时,集合元素的编号从 0 到 size-1,size 是最大元素的个数
-
判断两个元素是否属于同一集合,只需分别找到它们的根,再比较根是否相同即可
-
Find 操作和 Union 操作的时间复杂度分别为 O ( d ) O(d) O(d) 和 O ( 1 ) O(1) O(1),d 是树的深度
-
[>] 并查集实现的优化
极端情况下,n 个元素构成的集合树的深度为 n,则 Find 操作的最坏时间复杂度为 O ( n ) O(n) O(n)
- [i] Union 操作改进方法:
在做 Union 操作之前,首先判别子集中的成员数量,然后令成员少的根指向成员多的根,即把小树合并到大树,为此可令根结点的绝对值保存集合树中的成员数量
代码:
- [i] Find 操作改进方法:
当所查元素 x 不在树的第二层时,在算法中增加一个“压缩路径”的功能,即将从根到元素 x 路径上的所有元素都变成根的孩子
代码:
- 通过 Find 操作的“压缩路径”优化后,可使集合树的深度不超过 O ( a ( n ) ) O(a(n)) O(a(n)),其中 a ( n ) a(n) a(n) 是一个增长及其缓慢的函数,对于常见的正整数 n,通常 a ( n ) ≤ 4 a(n)≤4 a(n)≤4
小节选择题答案
序号 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
答案 | C | C | B | D | B | B | A | D | D | ||||
序号 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | ||||
答案 | D | B | D | ||||||||||
- 非叶结点:在哈夫曼树中无度为 1 的结点,非叶节点的额总数为 n-1,结点总数为 2 n-1
- 已知字符的编码,说明它已经是叶子结点,不可以接着再往下走了
- 码字为叶子结点,所以这道题是想看有多少叶子结点
- n 0 + n 1 + n 2 = 215 , n 2 = n 0 − 1 , n 1 = 0 n_0+n_1+n_2=215,n_2=n_0-1,n_1=0 n0+n1+n2=215,n2=n0−1,n1=0
- n 0 + n 0 − 1 = 215 , n 0 = 108 n_0+n_0-1=215,n_0=108 n0+n0−1=215,n0=108
- 关于哈夫曼树的说法,错误的是:
- I,哈夫曼结点总数= n 0 + n 1 + n 2 = n 0 + n 0 − 1 = 2 n 0 − 1 n_0+n_1+n_2=n_0+n_0-1=2n_0-1 n0+n1+n2=n0+n0−1=2n0−1, 偶数-1 注定是奇数