2-1 树的定义
定义树的一种自然的方式是递归的方法。一棵树是一些节点的集合,这个集合可以是空集,若非空,则一颗树由称做根的节点r以及0个或多个非空的子树组成,这些子树中每一课的根都被来自根r的一条有向的边所连接。
每一棵子树的根叫做根r的儿子,而r是每一棵子树的根的父亲。
每个节点都可以有任意多的儿子,也可能是零个儿子,没有儿子的节点称为树叶;具有相同父亲的节点成为兄弟。用类似的方法可以定义祖父的孙子的关系。
图 1-1 一颗具体的树
如图1-1,节点A是根。节点E有一个父亲和两个儿子I、J,节点K是树叶,节点K、L、M是兄弟。
从节点N1到Nk的路径定义为节点N1,N2,……Nk的一个序列,使得对于1<=i<=k,节点 Ni是节点N(i+1)的父亲,也就说如果存在Ni到N(i+1)的一条路径,那么Ni是N(i+1)的“长辈”,即图1-1中A到K就是一条路径,A到D到H同样也是一条路径。
对于任意节点Ni,Ni的深度为从根到Ni的唯一路径的长,因此根的深度为0,图1-1中C的深度为2,它到根H的唯一路径A->D->C的长度为2;Ni的高是Ni到一片树叶的最长路径的长,因此所有树叶的高都为0,图1-1中E的高度则为2。一颗树的深度等于它的最深的树叶的深度,该深度总是等于这棵树的高。
2-2 树的实现
想要实现树,每一个节点除了数据之外,还要有一些指针,指向这个节点的每一个儿子,然而,每个节点的儿子数是未知的,因此想要直接建立每个儿子节点的直接链接时不可行的。通常,我们将每个节点的所有儿子都放在树节点的链表中,如图1-2,就是一个典型的声明。
图1-2:树的节点声明(代码)
树的节点声明
图中向下的箭头是指向FirstChild(第一儿子)的指针。从左到右的箭头是指向NextSibling(下一兄弟)的指针,图1-2表示的树是图1-1所表示的树的第一儿子/下一兄弟的表示法。
2-3 二叉树
二叉树是一颗每个节点都不能有多于两个儿子的树。这两个子树有左右之分,次序也不能任意颠倒。
几种特殊的二叉树:
- 斜树:斜树分为左斜树和右斜树,它们分别指所有节点只有左节点/右节点的树。
- 满二叉树:除最后一层无任何子节点外,每一层上的所有结点都有两个子结点的二叉树。
- 完全二叉树:一棵深度为k的有n个结点的二叉树,对树中的结点按从上至下、从左到右的顺序进行编号,如果编号为i(1≤i≤n)的结点与满二叉树中编号为i的结点在二叉树中的位置相同,则这棵二叉树称为完全二叉树。
- 二叉排序树:若左子树不空,则左子树上所有结点的值均小于它的根结点的值;若右子树不空,则右子树上所有结点的值均大于它的根结点的值的树叫做二叉排序树。
- 平衡二叉树:树上任一结点的左子树和右子树的深度之差(绝)不超过1。
二叉树的遍历:
图1-3