12. 树
- 树反映了一种层级关系: 一个学校有若干学院、一个学院有若干专业、一个专业有若干老师.
12.1 例子
图 1. 树.
观察:
- 树是一种特殊的图;
- 有一个树根;
- 除树根之外, 其它节点均有父节点;
- 没有子节点的节点称为叶节点;
- 从任意节点到树根都只有一条唯一的路径.
思考: 树的边有向还是无向?
12.2 定义
Let ϕ \phi ϕ be the empty node, a tree is a triple T = ( V , r , p ) T = (\mathbf{V}, r, p) T=(V,r,p) where
- V ≠ ∅ \mathbf{V} \ne \emptyset V=∅ is the set of nodes;
- r ∈ V r \in \mathbf{V} r∈V is the root node;
-
p
:
V
∪
{
ϕ
}
→
V
∪
{
ϕ
}
p: \mathbf{V} \cup \{\phi\} \to \mathbf{V} \cup \{\phi\}
p:V∪{ϕ}→V∪{ϕ} is the parent mapping satisfying
- p ( r ) = ϕ p(r) = \phi p(r)=ϕ;
- ∀ v ∈ V \forall v \in \mathbf{V} ∀v∈V, ∃ ! n ≥ 0 \exist ! n \ge 0 ∃!n≥0, st. p ( n ) ( v ) = r p^{(n)}(v) = r p(n)(v)=r.
最后一行源码: \forall v \in \mathbf{V}, \exist ! n \ge 0, st. p^{(n)}(v) = r
分析:
- ϕ \phi ϕ 可以看作是常量, 对任意树都有效, 因此可以不出现在元组里面;
- 不同元组可以有不同特性, 甚至这里的元组 r r r 是 V \mathbf{V} V 的元素;
- p ( 2 ) ( v ) = p ( p ( v ) ) p^{(2)}(v) = p(p(v)) p(2)(v)=p(p(v)). 可以理解为: v v v 的 2 阶父节点;
- 最后一行读作: 对于任意的节点 v v v, 存在唯一的自然数 n n n, 使得 (满足) v v v 的第 n n n 阶父节点为 r r r;
- 唯一性表示既可达又没有环;
- p ( 0 ) ( v ) ≡ v p^{(0)}(v) \equiv v p(0)(v)≡v, 因此该条件考虑了 r r r 到 r r r;
- n n n 可以看作是节点所在的层, n = 0 n = 0 n=0 时只有根节点.
12.3 Java 代码
public class Tree {
/**
* 节点数. 表示节点 v_0 至 v_{n-1}.
*/
int n;
/**
* 根节点. 0 至 n-1.
*/
int root;
/**
* 父节点.
*/
int[] parent;
/**
* 构造一棵树, 第一个节点为根节点, 其余节点均为其直接子节点, 也均为叶节点.
*/
public Tree(int paraN) {
n = paraN;
parent = new int[n];
parent[0] = -1; // -1 即 \phi
}// Of the constructor
}//Of class Tree
分析:
- 代码与定义的统一: 3-元组与 3 个成员变量. 写完程序又回去整理定义.
- parent 函数可以用一维数组表示.
- − 1 -1 −1 表示 ϕ \phi ϕ.
- 程序里面, 数据本身没有保障可达性、唯一性. 这和无向图的情况一致 (连接矩阵对称).
12.4 作业
- 自己画一棵树, 将其元组各部分写出来 (特别是函数 p p p).
- 针对该树, 将代码中的变量值写出来 (特别是 parent 数组).