# 森林/树/二叉树相关问题(v1)
文章目录
森林/树/二叉树相关问题(v1)
树转化二叉树
- 记:将一般树或者m叉树转化为二叉树的函数为
T2BT(T)
(参数T是一般树)- 注意一般树和m叉树不见得是一回事,关键类比二叉树中,孩子的有序性和相对有序性(特别是独生子树的顺序)
- 按照层次遍历法一次处理树的每一个结点
- 在处理任意一个结点的时候,只关心两个方面的东西
- 是否有孩子(如果有则只关心第一个孩子)
- 没有的话则该结点的左子树缺失
- 是否有右兄弟(如果有,则该结点有右孩子)
- 没有的话,该结点右孩子缺失
- 一定小心不要把第一个孩子之外的其他孩子作为右孩子!!!
- 绘图美化
- 如果是手画,那么将原先是右兄弟的结点绕着其左兄弟顺时针旋转45度左右
- 是否有孩子(如果有则只关心第一个孩子)
- 应该注意到一个很特别的性质:转换后的二叉树是没有右子树的(对于根结点T)而言!
森林转化为二叉树
-
将森林转化为二叉树即相当于用孩子兄弟表示法表示森林。
-
在变化过程中,原森林某结点的第一个孩子结点作为它的左子树,它的兄弟作为它的右子树。
-
森林 F k F_k Fk是有若干棵树构成的(比如有k棵树, 分别记为 T 1 , T 2 , . . . T k 分别记为T_1,T_2,...T_k 分别记为T1,T2,...Tk)
-
这些树分别转换为二叉树(执行k次T2BT函数)
- 得到k棵二叉树,将他们的根结点用兄弟虚线起来,得到
T
s
T_s
Ts
- 将第一棵树的根也记为
T
s
T_s
Ts,该结点作为转化后的结果二叉树根结点
- 前面提到,T2BT调用后,得到的树是右子树缺失的,
- 那么将森林中的右侧的树作为左侧树的右子树就显得很合适
- 调用T2BT( T s T_s Ts)得到森林转化后的二叉树
- 将第一棵树的根也记为
T
s
T_s
Ts,该结点作为转化后的结果二叉树根结点
- 或者,干脆就是前一棵树 T i T_i Ti的右孩子结点链接到后一棵 T i + 1 T_{i+1} Ti+1根结点上,就行了
- 得到k棵二叉树,将他们的根结点用兄弟虚线起来,得到
T
s
T_s
Ts
森林/二叉树转化的结点的相关问题
记号说明
- 记转化前的树为T
- 转换前的森林为F
- 树T转化后的二叉树为BT
- BT=T2BT(T)
- 森林F转化为二叉树后为FBT
- FBT=F2BT(F)
左孩子问题(叶子结点问题)
-
根据树/森林转化为二叉树的算法:
-
森林中的叶结点由于没有孩子结点,那么转化为二叉树时,该结点就没有左结点,
-
所以 F 中叶结点的个数就等于T 中左孩子指针为空的结点个数
右孩子问题(分支结点问题)
-
另外,有一类问题,是关于树转化为二叉树后右孩子缺失问题
-
通过上面的转化算法可以看到,任意一个结点,
-
只要它有右兄弟,那么在BT中就不会右孩子缺失
-
没有右兄弟,那么在BT中一定会缺失右孩子
-
更一般的,如果接结点x是其双亲结点的最右孩子结点,那么它在BT中也是右孩子缺失的
- 因此,如果某个结点是其双亲结点的独生子结点,那么它在BT必然是右孩子缺失的
-
即,每个非终端结点,其所有孩子结点在转换后,最后一个孩子的右指针为空
- 注意,这仅仅覆盖了全树的n-1个结点(根结点意外的结点有孩子结点的身份)
- 树T中,只有根结点T不作为任何其他结点的孩子(孩子结点无法覆盖全树)
- 而根结点转换后,也是右指针为空的
- 因此转化后的二叉树中,右指针为空的结点数=
T的分支结点数+1
-
但是另一方面,我们的转换算法T2BT告诉我们,根结点也要被当一个左孩子(犹如它之上还有一个虚拟双亲结点S)
- 这意味着我们可以同一地考察全树的所有结点,它们都有
孩子结点的身份
- 因此转化后的二叉树中,右指针为空的结点数=
T的分支结点数+1
(包括虚拟的根结点的双亲结点S)
- 这意味着我们可以同一地考察全树的所有结点,它们都有
-
-
-
因此,BT中右孩子缺失的结点总数是
T中分支结点数+1
思路1(verbose):
-
没有双亲结点的:(第一层结点)
- 仅有根结点,我们知道根结点在BT中一定是右孩子缺失的
-
有双亲结点的:作以下定义(RMC)(对于第2~h层):
- 结点x有双亲结点,而且是其双亲结点的最后一个孩子(包括唯一孩子的情况),那么这个结点是RMC(RightMostChild)的
- 另外要考虑根结点,因为我们的转换算法T2BT告诉我们,根结点也要被当一个左孩子(犹如它之上还有一个虚拟结点),因此也特别地把根结点归为RMC类的.
-
直接统计RMC的含义是明显的,但是并不方便
- 一个RMC会对应有一个上层分支结点(这个歌RMC结点的双亲结点)
- 第i层的RMC数量就是第i-1层的分支结点数量
- 一个RMC会对应有一个上层分支结点(这个歌RMC结点的双亲结点)
-
那么BT中的右孩子缺失的结点数就是B中的
RMC结点总数+1(根结点)
- 因为,每个分支结点都会提供一个(且只有一个)RM类的子节点结点
- T的根结点由于没有双亲结点,因此要单独考虑
或者更直接(concise)
- 定义WRS(WithoutRightSibling)结点是树T中右兄弟缺失的结点
- 下面统计各层的WRS数量(
L
(
i
)
表示第
i
层的
W
R
S
的数量
L(i)表示第i层的WRS的数量
L(i)表示第i层的WRS的数量)
- B N ( b r a n c h N o d e ) 分支结点 , B N ( i ) 表示第 i 层的分支结点数量 BN(branchNode)分支结点,BN(i)表示第i层的分支结点数量 BN(branchNode)分支结点,BN(i)表示第i层的分支结点数量
- L ( 1 ) = 1 L(1)=1 L(1)=1(根结点是WRS)
- L ( 2 ) = B N ( 1 ) = 1 L(2)=BN(1)=1 L(2)=BN(1)=1(最后一个结点(根结点的最右孩子是WRS))
- L ( 3 ) = B N ( 2 ) L(3)=BN(2) L(3)=BN(2)
- ⋮ \vdots ⋮
- L ( h ) = B N ( h − 1 ) L(h)=BN(h-1) L(h)=BN(h−1)
- 下面统计各层的WRS数量(
L
(
i
)
表示第
i
层的
W
R
S
的数量
L(i)表示第i层的WRS的数量
L(i)表示第i层的WRS的数量)
- 又因为所有分支结点(非叶子结点)都分布在** 1 ∼ h − 1 1\sim h-1 1∼h−1**层内, 所以树 T 的所有分支接结点 S u m B r a n c h N o d e s = S B N ( T ) = ∑ i = 1 h − 1 B N ( i ) 所以树T的所有分支接结点SumBranchNodes=SBN(T)=\sum\limits_{i=1}^{h-1}BN(i) 所以树T的所有分支接结点SumBranchNodes=SBN(T)=i=1∑h−1BN(i)
- 综上,T转化为BT后,所有右孩子缺失的结点数量 W R C ( B T ) = W R S ( T ) = ∑ i = 1 h L ( i ) = 1 + S B N ( T ) WRC(BT)=WRS(T)=\sum\limits_{i=1}^{h}L(i)=1+SBN(T) WRC(BT)=WRS(T)=i=1∑hL(i)=1+SBN(T)
- 如果一致一棵树的总结点数N,叶子结点总数SLN,那么可以求得该树的分支结点总数SBN(T)=N(T)-SLN(T)
- 这样T转化为BT后,具有右孩子缺失的结点总数 W R C ( B T ) = 1 + S B N ( T ) = 1 + N ( T ) − S L N ( T ) WRC(BT)=1+SBN(T)=1+N(T)-SLN(T) WRC(BT)=1+SBN(T)=1+N(T)−SLN(T)
对于森林
- 上述结论基于树T推导,对于森林F,计算公式在形式上是一样的
- 森林转化为二叉树前也要先将各棵树转换为二叉树,需要注意的仅是各棵二叉树的根结点
- 后一棵树(根结点)会成为前一棵树的右孩子,这样所有的树的根结点在链接完成后,仅有最后一棵树的根结点还是处于缺失的状态
- 因此,结论就是,森林F中所有树的分支结点总和+1(由最后一棵树的根结点在FBT中缺失右孩子)
- WRC(FBT)=1+SBN(F)=1+N(F)-SLN(F)
二叉树转换为森林b2m
二叉树拆分为二叉树森林
- 由于我们知道由树转化而成的二叉树是没有右子树的
- 所以,我们可以从大二叉树的右子树入手,将其右子树从大二叉树上断开,记为 T 1 T_1 T1
- 那么断开的
T
1
T_1
T1的根结点很显然是
T
1
T_1
T1
- 对 T 1 T_1 T1执行上述操作,知道最后被断开的右子树没有右子树为止
二叉树转为树
-
根据树转化为二叉树的算法,可以得到二叉树转化为树的算法
-
可以从根结点开始
-
按层次遍历的顺序将所有结点划分关系
-
比如当前处理结点x
-
如果没有左孩子,说明x本身没有孩子
- 否则将x的左孩子保留不动
-
如果有右孩子,那么将右孩子作为x的有兄弟
-
-
-
可以自底向上将二叉树还原为树
- 最底一层开始,从最右一个结点开始,它作为右子树,那么在原树中作为其双亲结点的最近邻右侧兄弟
树的遍历
-
这里的树是一般树
-
树的遍历和二叉树的遍历很相似
-
树T的先序遍历对应于T2BT(T)的先序遍历的结果序列是一致的
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
2021-09-27 css_选择器/规则集/属性和值(函数)/计算css选择器的优先级/兼容性规则集/块级元素和行内元素