608. 树节点
题目
表:Tree
±------------±-----+
| Column Name | Type |
±------------±-----+
| id | int |
| p_id | int |
±------------±-----+
id 是该表中具有唯一值的列。
该表的每行包含树中节点的 id 及其父节点的 id 信息。
给定的结构总是一个有效的树。
树中的每个节点可以是以下三种类型之一:
- “Leaf”:节点是叶子节点。
- “Root”:节点是树的根节点。
- “lnner”:节点既不是叶子节点也不是根节点。
编写一个解决方案来报告树中每个节点的类型。
以 任意顺序 返回结果表。
结果格式如下所示。
示例 1:
输入:
Tree table:
±—±-----+
| id | p_id |
±—±-----+
| 1 | null |
| 2 | 1 |
| 3 | 1 |
| 4 | 2 |
| 5 | 2 |
±—±-----+
输出:
±—±------+
| id | type |
±—±------+
| 1 | Root |
| 2 | Inner |
| 3 | Leaf |
| 4 | Leaf |
| 5 | Leaf |
±—±------+
解释:
节点 1 是根节点,因为它的父节点为空,并且它有子节点 2 和 3。
节点 2 是一个内部节点,因为它有父节点 1 和子节点 4 和 5。
节点 3、4 和 5 是叶子节点,因为它们有父节点而没有子节点。
分析
单独查询,结果合并,针对节点的不同条件去查找,然后合并结果
题解
# 分步查询
# 根节点的父节点为空
-- select id, 'Root' type from tree where p_id is NULL
-- # 叶子节点没有子节点,但有父节点
-- select id, 'Leaf' type from tree where id not in (
-- # 没有子节点就是在p_id列里不存在
-- select distinct p_id from tree where p_id is not NULL
-- ) and p_id is not NULL # 并且自己有父节点
-- # 内部节点,有孩子有父亲节点
-- select id, 'Inner' type from tree where id in(
-- # 自己也要出现在p_id列作为别人的父节点
-- select distinct p_id from tree where p_id is not NULL
-- ) and p_id is not NULL
# 将分步步骤连起来
# 根节点的父节点为空
select id, 'Root' type from tree where p_id is NULL
union
# 叶子节点没有子节点,但有父节点
select id, 'Leaf' type from tree where id not in (
# 没有子节点就是在p_id列里不存在
select distinct p_id from tree where p_id is not NULL
) and p_id is not NULL # 并且自己有父节点
union
# 内部节点,有孩子有父亲节点
select id, 'Inner' type from tree where id in(
# 自己也要出现在p_id列作为别人的父节点
select distinct p_id from tree where p_id is not NULL
) and p_id is not NULL
order by id