Appearance
题目
将森林 F 转换为对应的二叉树 T,F 中叶子的个数等于( )。
错因
A
凭直觉以为"森林叶子 ↔ 二叉树叶子"。但二叉树叶子要求左右指针都为空,而森林叶子在转换后只要求左指针为空(右指针可能指向"原森林中的下一个兄弟"或"森林中下一棵树的根")。所以森林叶数 ≥ 二叉树叶数(多出的是那些右指针非空但左指针空的节点)。
B
把"左空 OR 右空(但不全空)"当成了答案。度为 1 的二叉树节点 = 恰好一个孩子,可能是"左空右非空"或"左非空右空"——前者对应森林叶子(这部分对),后者对应"原森林中有孩子但没有右兄弟"的非叶节点(这部分错)。两类合并后必然多于森林叶数。
D
把孩子兄弟法的"右指针含义"搞反了。右指针对应"原森林中的下一个兄弟",右空意味着"没有下一个兄弟"——这是关于兄弟关系的,与"是不是叶子"无关。比如森林中一个有孩子但是父亲最后一个孩子的节点,右空但有左孩子,不是叶子。
总解析
孩子兄弟法(左孩子-右兄弟表示法)的转换规则:
森林中的每个节点 v 在二叉树中的指针含义:
| 二叉树指针 | 指向 |
|---|---|
| 左孩子 | v 在森林中的第一个孩子(如果有);否则空 |
| 右孩子 | v 在森林中的下一个兄弟(如果有)——同一父亲下的下一个,或下一棵树的根;否则空 |
关键映射:
节点 v 在森林中有孩子 ⟺ v 在二叉树中左指针非空
节点 v 在森林中没有孩子(即叶子) ⟺ v 在二叉树中左指针为空
推论:
森林中叶子的个数 = 森林中"无孩子的节点"个数 = 二叉树中"左指针为空的节点"个数 = 选项 C。
举例验证:
森林 F:
树1: A 树2: D
/ \ |
B C E
/ | \
F G H- F 中叶子:B, C, F, G, H → 5 个
按孩子兄弟法转成二叉树 T:
- A 的左孩子 = B(第一个孩子);A 的右孩子 = D(下一棵树的根)
- B 的左孩子 = 空(B 无孩子);B 的右孩子 = C(B 的下一个兄弟)
- C 的左孩子 = 空;C 的右孩子 = 空
- D 的左孩子 = E;D 的右孩子 = 空
- E 的左孩子 = F;E 的右孩子 = 空
- F 的左孩子 = 空;F 的右孩子 = G
- G 的左孩子 = 空;G 的右孩子 = H
- H 的左孩子 = 空;H 的右孩子 = 空
T 中左指针为空的节点:B, C, F, G, H → 5 个 ✓ 与 F 的叶子数相等。
速记:森林 ↔ 二叉树的一一对应中,"原节点是叶子"的信息被编码到二叉树的左指针上:左空 = 原叶子。右指针编码的是兄弟关系,与叶子身份无关。
最终答案是 C(T 中左孩子指针为空的结点个数)。