二叉树的定义有一定的难度,本贴详细描述如何逐步获得完美的版本。
在《数据结构》中,对二叉树的定义是描述性的。
Definition 1. A set of nodes form a binary tree if it is empty (no node) or:
a) Any node has at most one left child and one right child. A node is called the parent of its left or right child;
b) Any node except the root should have exactly one parent; and
c) There is exactly one node without parent, which will be called the root.
分析:
递归定义需要基础与归纳.
Definition 2. A set of nodes form a binary tree if it satisfies one of the following conditions:
a) It is empty;
b) It has only one node, which is called the root of the binary tree;
c) It has one left child, which is a root of another binary tree;
d) It has one right child, which is a root of another binary tree;
e) It has one left child and one right child, which are roots of binary trees, and the nodes of the left sub-tree and right sub-tree has no intersection.
分析:
为解决该问题, 一种极(piao)端(liang)的做法是:不承认空树. 可能读者要问: 这也行?对哒!我们写定义,是自己来创造一套系统,怎么方便怎么写,想怎么写就怎么写. 只要内部没有矛盾, 就是良好的系统
Definition 3. A set of nodes form a binary tree if it satisfies one of the following conditions:
a) It has only one node, which is called the root of the binary tree;
b) It has one left child and/or one right child, which are roots of binary trees, and the nodes of the left sub-tree and right sub-tree has no intersection.
分析:
既然我们已经用递归的方式定义 (描述) 了二叉树, 能否进一步, 用符号把它描述出来? 毕竟我们有成功的先例:
Definition 4 (Positive integer):
a) 1 is a positive integer;
b) if n n n is a positive integer, then n + 1 n + 1 n+1 is also a positive integer.
我们来尝试一下:
Definition 5 (binary tree):
a) A single node v v v is a binary tree with root v v v;
b) Let T i T_i Ti and T j T_j Tj be two binary trees with roots v i v_i vi and v j v_j vj, respectively. A binary tree with root v v v can have T i T_i Ti as its left child and/or T j T_j Tj as its right child.
这个乱七八糟的定义写得令人崩溃, 根本原因在于: 递归式的定义只适合于简单的集合及其元素. 特别地, 如果一个超集已经定义好, 要定义其中一个子集就比较容易.
如果要使用递归方式定义这种复杂的结构, 就好比写程序时要用一个浮点数来表示复数, 或者想骑着自行车登上月球, 都是不可行的.
元组就是为了定义模型而生的. 使用它来定义二叉树是再适合不过了. 它对应于面向程序设计中“类”的概念, 当然, 具体的一个元组就是实例, 也就是“对象”.
我们来分析二叉树涉及的几个方面:
a) 节点的集合, 包括根节点.
b) 根节点. 如前所述, 我们的二叉树不可以是空的, 所以必须有根结点.
c) 节点之间的关系: 左子节点、右子节点.
我们先来写一个简单的版本:
Definition 5: A binary tree is a quadraple B T = ( V , r , L , R ) BT = (\mathbf{V}, r, \mathbf{L}, \mathbf{R}) BT=(V,r,L,R), where
a) V \mathbf{V} V is the set of nodes;
b) r ∈ V r \in \mathbf{V} r∈V is the root;
c) L ⊂ V × V \mathbf{L} \subset \mathbf{V} \times \mathbf{V} L⊂V×V is the left child relation, where ⟨ v i , v j ⟩ ∈ L \langle v_i, v_j \rangle \in \mathbf{L} ⟨vi,vj⟩∈L indicates that v i v_i vi is the left child of v j v_j vj;
d) R ⊂ V × V \mathbf{R} \subset \mathbf{V} \times \mathbf{V} R⊂V×V is the left child relation, where ⟨ v i , v j ⟩ ∈ R \langle v_i, v_j \rangle \in \mathbf{R} ⟨vi,vj⟩∈R indicates that v i v_i vi is the right child of v j v_j vj.
优点: 这个定义把二叉树的几个要素都写出来了. 特别地, 虽然 r ∈ V r \in \mathbf{V} r∈V, 但 r r r 在元组中必须单独指定.
缺点: 这里没有把约束条件表达出来, 即二叉树的左右子树不相交.
为表达“左右子树不相交”的约束, 需要首先把左、右子树的节点集合表达出来. 这涉及到传递性问题, 即“左子节点的左子节点”属于左子树的节点集合. 另外, “左子节点的右子节点”也属于左子树的节点集合. 如何涵盖所有的情况呢?
我们引入更高档的玩艺儿: 有限状态自动机. 二叉树符合确定的有穷状态自动机的几个特征:
a) 有若干的节点, 它们构成状态;
b) 有一个开始状态, 即根节点;
c) 没有终止状态不重要, 因为我们这里并不是做语言的识别;
d) 有一个字母表, 即 {l, r};
e) 有状态的转移, 从某一节点读入字母 l 转到 左子树; 读入 r 转到右子树.
Definition 5: Let Σ = { l , r } \Sigma = \{\mathrm{l}, \mathrm{r}\} Σ={l,r} be the alphabet and ϕ \phi ϕ be a null node. A binary tree is a triple B T = ( V , r , c ) BT = (\mathbf{V}, r, c) BT=(V,r,c), where
a) V = { v 1 , v 2 , … , v n } \mathbf{V} = \{v_1, v_2, \dots, v_n\} V={v1,v2,…,vn} is the set of nodes;
b) r ∈ V r \in \mathbf{V} r∈V is the root; and
c) c : V ∪ { ϕ } × Σ ∗ → V ∪ { ϕ } c: \mathbf{V} \cup \{\phi\} \times \Sigma^* \rightarrow \mathbf{V} \cup \{\phi\} c:V∪{ϕ}×Σ∗→V∪{ϕ} is the mapping function satisfying: ∀ v ∈ V \forall v \in \mathbf{V} ∀v∈V, ∃ \exists ∃ 1 s ∈ Σ ∗ s \in \Sigma^* s∈Σ∗, st. c ( s ) = v c(s) = v c(s)=v;
分析:
a) 函数 c c c 通过对字符串的处理, 描述了节点之间的关系;
b) 支持空串, 因此 r r r 到自己的路径也是唯一的;
c) 路径的存在性, 保证了节点之间的连通性;
d) 路径的唯一性, 避免了环的出现;
e) 任意节点到空节点的路径都有无数条, 条件 c) 说存在唯一的时候, 排除了 ϕ \phi ϕ;
f) 节点 ϕ \phi ϕ 是一个黑洞, 绝招是吸星大法, 把后面的所有字符吸收.
由于前面已经写过一遍了, 这里容易写成正确的样子.
定义树.
提示: 字母表仅有一个字母; 空节点应该是根节点的父节点, 吸星大法靠它了.