树和森林的遍历及其与二叉树的转换是数据结构中的重要内容,理解其原理有助于将多叉树问题转化为更易处理的二叉树结构。
1. 树的遍历:
- 先根遍历(Root → Children): 先访问根节点,然后从左到右依次进行先根遍历各子树。这种遍历方式对应于该树转换成二叉树后的先序遍历。
- 后根遍历(Children → Root): 先从左到右依次后根遍历各个子树,最后访问根节点,等价于对应二叉树的中序遍历。
2. 森林的遍历:
- 先序遍历: 访问第一棵树的根节点 → 先序遍历该根的子女森林(即该根的所有子树构成的森林)→ 先序遍历剩下的树构成的森林。这与对应二叉树的先序遍历一致。
- 中序遍历: 中序遍历第一棵树的子女森林 → 访问第一棵树的根节点 → 中序遍历剩余森林。这等价于对应二叉树的中序遍历。
3. 树/森林 与 二叉树 的转换:
使用“孩子兄弟表示法”(Left Child - Right Sibling Representation)实现转换:
- 每个节点的 第一个孩子 作为其在二叉树中的左孩子;
- 该节点的 下一个兄弟 作为其在二叉树中的右孩子。
这样,一棵树或一个森林可以唯一地转换为一个二叉树,且物理存储结构完全相同(均为二叉链表),只是逻辑解释不同。
意义与应用:
通过这种转换,可以将对树或森林的操作统一为对二叉树的操作,从而复用成熟的二叉树算法(如遍历、查找、插入、删除等),简化程序设计与实现。
# 孩子兄弟表示法的节点定义示例
class TreeNode:
def __init__(self, val=0):
self.val = val
self.first_child = None # 左孩子:第一个孩子
self.next_sibling = None # 右兄弟:下一个兄弟
通过孩子兄弟表示法(也称左孩子-右兄弟表示法)可以将一棵普通的树转换为唯一的二叉树。其核心思想是:
每个节点的“第一个孩子”作为其左子树,“下一个兄弟”作为其右子树。
✅ 转换步骤:
- 确定每个节点的第一个孩子(最左边的孩子)。
- 确定每个节点的下一个兄弟(在同一父节点下的右邻兄弟)。
- 对于每个节点:
- 将“第一个孩子”链接到其左指针;
- 将“下一个兄弟”链接到其右指针。
- 忽略其他孩子之间的连接,仅保留左孩子和右兄弟关系。
- 最终形成的结构即为对应的二叉树。
🌲 示例:普通树结构
假设有一棵树如下:
A
/ | \
B C D
/ \ |
E F G
/
H
第一步:找出每个节点的关系
- A 的孩子:B, C, D → B 是第一个孩子,C 是 B 的兄弟,D 是 C 的兄弟
- B 的孩子:E, F → E 是第一个孩子,F 是 E 的兄弟
- F 的孩子:H → H 是 F 的第一个孩子
- C、D、E、G、H 无孩子或兄弟
第二步:构建孩子兄弟链
使用两个指针:
first_child→ 左子树next_sibling→ 右子树
转换过程:
A 的 first_child = B,next_sibling = null
B 的 first_child = E,next_sibling = C
C 的 first_child = null,next_sibling = D
D 的 first_child = G,next_sibling = null
E 的 first_child = null,next_sibling = F
F 的 first_child = H,next_sibling = null
G/H 的 first_child = null,next_sibling = null
第三步:画出对应的二叉树结构
根据上述规则构造二叉树:
A
/
B
/ \
E C
\ \
F D
/
H
\
G
注意:这里有个关键点!在原树中,G 是 D 的孩子,所以在二叉树中 G 应该是 D 的 left;而 H 是 F 的孩子 → H 是 F 的 left。
正确重构后的对应二叉树应为:
A
/
B
/ \
E C
\ \
F D
/ /
H G
✔️ 解释:
- A 左孩子是 B(第一个孩子),右为空(无兄弟)
- B 左是 E(第一个孩子),右是 C(下一个兄弟)
- E 右是 F(兄弟),左无
- F 左是 H(第一个孩子)
- C 右是 D(兄弟)
- D 左是 G(第一个孩子)
🔁 总结转换规则(图解要点):
| 原树中的关系 | 在二叉树中的表示 |
|---|---|
| 节点的第一个孩子 | → 该节点的左子树 |
| 节点的下一个兄弟 | → 该节点的右子树 |
| 其他孩子 | 通过兄弟链间接连接 |
💡 优点与意义:
- 所有树都可以唯一地转换成一个等价的二叉树;
- 存储结构统一为二叉链表,便于程序实现;
- 可复用二叉树的遍历算法来处理普通树;
- 多棵树组成的森林也可类似转换为森林对应的二叉树集合(见下文扩展)。
# Python 节点定义示例
class TreeToBinaryNode:
def __init__(self, val):
self.val = val
self.left = None # 第一个孩子
self.right = None # 下一个兄弟


1万+

被折叠的 条评论
为什么被折叠?



