0
点赞
收藏
分享

微信扫一扫

# 森林/树/二叉树相关问题(v1)

天际孤狼 2022-10-02 阅读 181


文章目录

  • ​​森林/树/二叉树相关问题(v1)​​
  • ​​树转化二叉树​​
  • ​​森林转化为二叉树​​
  • ​​森林/二叉树转化的结点的相关问题​​
  • ​​记号说明​​
  • ​​左孩子问题(叶子结点问题)​​
  • ​​右孩子问题(分支结点问题)​​
  • ​​思路1(verbose):​​
  • ​​或者更直接(concise)​​
  • ​​对于森林​​
  • ​​二叉树转换为森林b2m​​
  • ​​二叉树拆分为二叉树森林​​
  • ​​二叉树转为树​​
  • ​​树的遍历​​

森林/树/二叉树相关问题(v1)

树转化二叉树

  • 记:将一般树或者m叉树转化为二叉树的函数为​​T2BT(T)​​(参数T是一般树)
  • 注意一般树和m叉树不见得是一回事,关键类比二叉树中,孩子的有序性和相对有序性(特别是独生子树的顺序)
  • 按照层次遍历法一次处理树的每一个结点
  • 在处理任意一个结点的时候,只关心两个方面的东西
  • 是否有孩子(如果有则只关心第一个孩子)
  • 没有的话则该结点的左子树缺失
  • 是否有右兄弟(如果有,则该结点有右孩子)
  • 没有的话,该结点右孩子缺失
  • 一定小心不要把第一个孩子之外的其他孩子作为右孩子!!!
  • 绘图美化
  • 如果是手画,那么将原先是右兄弟的结点绕着其左兄弟顺时针旋转45度左右
  • 应该注意到一个很特别的性质:转换后的二叉树是没有右子树的(对于根结点T)而言!

森林转化为二叉树

  • 将森林转化为二叉树即相当于用孩子兄弟表示法表示森林。
  • 在变化过程中,原森林某结点的第一个孩子结点作为它的左子树,它的兄弟作为它的右子树。
  • 森林是有若干棵树构成的(比如有k棵树,)
  • 这些树分别转换为二叉树(执行k次T2BT函数)
  • 得到k棵二叉树,将他们的根结点用兄弟虚线起来,得到
  • 将第一棵树的根也记为,该结点作为转化后的结果二叉树根结点
  • 前面提到,T2BT调用后,得到的树是右子树缺失的,
  • 那么将森林中的右侧的树作为左侧树的右子树就显得很合适
  • 调用T2BT()得到森林转化后的二叉树
  • 或者,干脆就是前一棵树的右孩子结点链接到后一棵根结点上,就行了

森林/二叉树转化的结点的相关问题

记号说明

  • 记转化前的树为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层的分支结点数量
  • 那么BT中的右孩子缺失的结点数就是B中的​​RMC结点总数+1(根结点)​
  • 因为,每个分支结点都会提供一个(且只有一个)RM类的子节点结点
  • T的根结点由于没有双亲结点,因此要单独考虑

或者更直接(concise)

  • 定义WRS(WithoutRightSibling)结点是树T中右兄弟缺失的结点
  • 下面统计各层的WRS数量()
  • (根结点是WRS)
  • (最后一个结点(根结点的最右孩子是WRS))
  • 又因为所有分支结点(非叶子结点)都分布在****层内,
  • 综上,T转化为BT后,所有右孩子缺失的结点数量
  • 如果一致一棵树的总结点数N,叶子结点总数SLN,那么可以求得该树的分支结点总数SBN(T)=N(T)-SLN(T)
  • 这样T转化为BT后,具有右孩子缺失的结点总数

对于森林

  • 上述结论基于树T推导,对于森林F,计算公式在形式上是一样的
  • 森林转化为二叉树前也要先将各棵树转换为二叉树,需要注意的仅是各棵二叉树的根结点
  • 后一棵树(根结点)会成为前一棵树的右孩子,这样所有的树的根结点在链接完成后,仅有最后一棵树的根结点还是处于缺失的状态
  • 因此,结论就是,森林F中所有树的分支结点总和+1(由最后一棵树的根结点在FBT中缺失右孩子)
  • WRC(FBT)=1+SBN(F)=1+N(F)-SLN(F)

二叉树转换为森林b2m

二叉树拆分为二叉树森林

  • 由于我们知道由树转化而成的二叉树是没有右子树的
  • 所以,我们可以从大二叉树的右子树入手,将其右子树从大二叉树上断开,记为
  • 那么断开的的根结点很显然是
  • 执行上述操作,知道最后被断开的右子树没有右子树为止

二叉树转为树

  • 根据树转化为二叉树的算法,可以得到二叉树转化为树的算法
  • 可以从根结点开始
  • 按层次遍历的顺序将所有结点划分关系
  • 比如当前处理结点x
  • 如果没有左孩子,说明x本身没有孩子
  • 否则将x的左孩子保留不动
  • 如果有右孩子,那么将右孩子作为x的有兄弟
  • 可以自底向上将二叉树还原为树
  • 最底一层开始,从最右一个结点开始,它作为右子树,那么在原树中作为其双亲结点的最近邻右侧兄弟

树的遍历

  • 这里的树是一般树
  • 树的遍历和二叉树的遍历很相似
  • 树T的先序遍历对应于T2BT(T)的先序遍历的结果序列是一致的


举报

相关推荐

0 条评论