首页/数据结构/04-tree/森林与二叉树的转换 🔗 在 Obsidian 中打开
数据结构 · 树与二叉树

森林与二叉树的转换

难度 ★★★重要度 ★★ 考查频率 低 森林二叉树转换
速查
转换核心是孩子兄弟表示法左指针 = 第一个孩子右指针 = 下一个兄弟。遍历对应:树的先根 = 二叉树先序;树的后根 = 二叉树中序(高频易错)。

核心概念

树、森林与二叉树之间可以相互转换,转换的核心是孩子兄弟表示法(又称二叉链表表示法)。

核心原则

  • 左指针 → 第一个孩子(长子)
  • 右指针 → 下一个兄弟(右邻兄弟)
为什么能转任意结点的「孩子个数」是不定的,但「第一个孩子」和「下一个兄弟」各自最多只有一个 —— 于是任意树都能塞进只有两个指针的二叉链表里,且信息不丢失。这就是转换唯一可逆的原因。

一、树 → 二叉树

转换步骤

  1. 在所有相邻兄弟之间加一条连线;
  2. 对每个结点,只保留与第一个孩子的连线,删除与其他孩子的连线;
  3. 以树根为轴,顺时针旋转 45° 整理。

手算示例

原始树:

       A
     / | \
    B  C  D
   / \
  E   F

步骤 1:加兄弟连线

       A
     / | \
    B--C--D
   / \
  E---F

步骤 2:只保留与第一个孩子的连线

       A
      /
     B---C---D
    /
   E---F

步骤 3:旋转整理,得到二叉树

     A
    /
   B
  / \
 E   C
  \   \
   F   D
原树中的关系二叉树中的位置
A 的第一个孩子是 BA 的孩子是 B
B 的下一个兄弟是 CB 的孩子是 C
C 的下一个兄弟是 DC 的孩子是 D
B 的第一个孩子是 EB 的孩子是 E
E 的下一个兄弟是 FE 的孩子是 F
一条铁律单棵树转出来的二叉树,根一定没有右孩子(因为根没有兄弟)。这是判卷时的第一检查点。

二、二叉树 → 树

转换步骤(树 → 二叉树的逆过程)

  1. 从根开始,沿左孩子链找到所有结点;
  2. 把每个结点的右孩子链上的结点,统统提升为它的兄弟(即挂到它双亲名下);
  3. 删除多余连线,整理层次。

手算示例

原始二叉树:

     A
    /
   B
  / \
 E   C
  \   \
   F   D

还原过程:

  1. A 沿左链:A → B → E;
  2. B 的右孩子 C → C 成为 B 的兄弟(即 A 的孩子);
  3. C 的右孩子 D → D 成为 C 的兄弟(即 A 的孩子);
  4. E 的右孩子 F → F 成为 E 的兄弟(即 B 的孩子)。

结果:

       A
     / | \
    B  C  D
   / \
  E   F

三、森林 → 二叉树

转换步骤

  1. 将森林中每棵树分别转换为二叉树;
  2. 第一棵树的根作为结果二叉树的根
  3. 第二棵树的根作为第一棵树根的右孩子
  4. 第三棵树的根作为第二棵树根的右孩子;依次类推。

手算示例(3 棵树的森林)

树1:      A          树2:    E        树3:    G
        /   \               /                / \
       B     C             F                H   I
      /
     D

步骤 1:各树分别转二叉树(左孩子右兄弟)

树1:            树2:      树3:
  A                E          G
 /                /          /
B                F          H
/ \                          \
D   C                         I

步骤 2:合并 —— 后一棵树的根接为前一棵树根的右孩子

        A
       / \
      B   E
     / \   \
    D   C   G
           /
          H
           \
            I
勘误提示源笔记该例的最终图把 F 画在了 E 的右侧、G 与 F 并列。按规则:E 的左孩子是 F(E 的第一个孩子),E 的右孩子是 G(下一棵树的根)。本页已按「左孩子右兄弟 + 根右链」修正。三棵树的根 A → E → G 必须构成一条右孩子链

完整的最终二叉树(含 F):

        A
       / \
      B   E
     / \  / \
    D   C F  G
            /
           H
            \
             I

四、二叉树 → 森林

  1. 从根开始,沿右孩子链逐个断开,每个断点结点各作为一棵树的根;
  2. 对得到的每棵二叉树,按「二叉树 → 树」的方法还原。
判断树的棵数结果森林的树的棵数 = 根的右孩子链长度 + 1。若二叉树的根没有右孩子,则森林只有 1 棵树(即它本来就是由单棵树转来的)。

关键性质

转换前后遍历序列的对应关系

树 / 森林的遍历对应二叉树的遍历
先根遍历先序遍历
后根遍历中序遍历
层次遍历层次遍历(仅形式对应,序列一般不同)
最高频考点树的后根遍历对应转换后二叉树的中序遍历不是后序遍历!

转换的唯一性

方向唯一性
树 → 二叉树唯一
二叉树 → 树唯一(前提:该二叉树的根无右孩子)
森林 → 二叉树唯一
二叉树 → 森林唯一

常见考法

题型一 · 画转换结果给定一棵树或森林,画出转换后的二叉树(记得检查「根有无右孩子」)。
题型二 · 遍历序列对应由树的先根 / 后根遍历,反推二叉树的先序 / 中序序列,或反向推。
题型三 · 森林的遍历

森林先序 = 第一棵树的先根遍历 + 剩余森林的先序遍历
森林中序 = 第一棵树的后根遍历 + 剩余森林的中序遍历

题型四 · 已知二叉树求原树 / 森林沿右链断开数出树的棵数,再逐棵还原。

易错点

必记
  1. 树的后根遍历 = 二叉树的中序遍历,不是后序遍历!
  2. 森林先序 = 各树先根遍历的拼接
  3. 森林中序 = 各树后根遍历的拼接
  4. 左 = 第一个孩子,右 = 兄弟,不要搞反。
  5. 二叉树转森林沿右链断开:根的右孩子就是第二棵树的根。

核心结论

  • 树 / 森林与二叉树可相互转换,且转换唯一
  • 转换核心口诀:左孩子、右兄弟
  • 树的先根遍历 = 二叉树的先序遍历。
  • 树的后根遍历 = 二叉树的中序遍历(高频易错,必背)。
  • 森林先序 = 各树先根遍历拼接;森林中序 = 各树后根遍历拼接。
  • 由单棵树转出的二叉树,根一定无右孩子

记忆卡片

树转二叉树的核心规则?
左孩子右兄弟:左指针指第一个孩子,右指针指下一个兄弟。
树的后根遍历对应二叉树的什么遍历?
中序遍历(易错点,不是后序)。
森林转二叉树时第二棵树的根放哪?
作为第一棵树根的右孩子;第三棵接在第二棵根的右孩子,依次类推。
二叉树转森林如何分割?
从根沿右孩子链断开,每个断点作为一棵独立树的根。
树 → 二叉树的转换唯一吗?
唯一。每棵树对应唯一一棵「根无右孩子」的二叉树。
怎样一眼看出结果森林有几棵树?
数根的右孩子链长度,棵数 = 链长 + 1。

交互动画 · 树 → 二叉树四步走

1 / 5 步 · ① 原树
A B C D E F A B C D E F A B C D E F A B E C F D 右·接森林 A B E C F D G H
长子边(→ 左指针) 兄弟边(→ 右指针) 被删除的边
① 原树:A 有三个孩子 B、C、D;B 有两个孩子 E、F
点「播放」或「下一步」沿着四步走:连兄弟 → 删非长子 → 旋转 → 森林接右
看第 ④ 步结果二叉树里 A 没有右孩子 —— 因为 A 是单棵树的根,没有兄弟。如果这是森林的第一棵树,A 的右孩子位就会接上第二棵树的根。

相关知识点

(暂无关联知识点)

↑ 源笔记 front-matter 中 related 为空;本页右上「在 Obsidian 中打开」可跳回源笔记。