树和二叉树
作者寄语:
树型结构是一种重要的非线性数据结构。其中以树和二叉树最为常用。树是以分支关系定义的层次结构,是一种一对多的数据结构。
树的定义和基本术语
定义
树(Tree)是n(n≥0)个结点的有限集。在任意一个非空树中:(1)有且仅有一个特定的根(Root)结点;(2)当n>1的时候,其余结点可分为m(m≥0)个互不相交的有限集T1,T2...Tn,其中每一个集合本身又是一棵树,并且称为根的子树(SubTree)。

结点的分类
树的结点包含一个数据元素及若干指向其子树的分支。结点拥有的子树数称为结点的度(Degree)。度为0的结点称为叶子节点(Leaf)或终端结点;度不为0的结点称为非终端结点或分支结点。除根节点外,分支结点也称为内部节点。树的度就是树内各结点的度的最大值。

结点间的关系
结点的子树的根节点称为该结点的孩子结点(Child),该节点称为孩子结点的双亲结点(Parent),同一个双亲结点之间互称为兄弟结点(Sibling),结点的祖先是从根节点到该节点所经分支上的所有结点,以某节点为根的子树中的任一结点都成为该节点的子孙。

结点的层次
结点的层次(Level)从根定义开始,根为第一层,根的孩子为第二层。若某节点在第L层,则其子树是在第L+1层。其双亲在同一层的结点互称为堂兄弟,树中结点的最大层次称为树的深度或高度。

如果将树中结点的各子树看成从左至右是有次序的,不能互换的,则称该树是有序树,否则称为无序树。上图就是一个有序树。
森林(Forest) 是m(m≥0)棵不相交的树的集合。对树中每个结点而言,其子树的集合即为森林。

树的抽象数据类型
ADT Tree {
数据对象:
D = {N, E},其中 N 是节点的集合,E 是边的集合。
数据关系:
R = {<parent, child> | parent, child ∈ N},表示父子关系。
基本操作:
InitTree(&T):初始化树。
DestroyTree(&T):销毁树。
TreeEmpty(T):判断树是否为空。
Root(T):返回树的根节点。
Parent(T, node):返回节点的父节点。
FirstChild(T, node):返回节点的第一个子节点。
NextSibling(T, node):返回节点的下一个兄弟节点。
InsertChild(&T, parent, node):插入子节点。
DeleteChild(&T, parent, i):删除子节点。
PreOrderTraverse(T, visit):前序遍历。
InOrderTraverse(T, visit):中序遍历。
PostOrderTraverse(T, visit):后序遍历。
LevelOrderTraverse(T, visit):层次遍历。
TreeDepth(T):返回树的深度。
TreeSize(T):返回树的节点总数。
IsLeaf(T, node):判断节点是否为叶子节点。
}
树的链式存储结构
双亲表示法: 假设以一组连续空间存储树的结点,同时在每个结点中,附设一个指示器指示其双亲结点在数组中的位置。
孩子表示法: 把每个结点的孩子结点排列起来,以单链表作为存储结构,则n个结点有n个孩子链表,如果是叶子节点则此单链表为空。然后n个头指针又组成一个线性表,采用顺序存储结构,存放在一维数组中。
孩子兄弟表示法: 任意一棵树,它的结点的第一个孩子如果存在就是唯一的,它的右兄弟如果存在也是唯一的,因此可以设置两个指针分别指向该节点的第一个孩子和此节点的右兄弟。
二叉树
定义
二叉树(Binary Tree)是一种比较特殊的树形结构,它的特点是每个结点至多只有两棵子树(即二叉树中不存在度大于2的结点),并且,二叉树的子树是有左右之分的,其次序不能任意颠倒。

二叉树的抽象数据类型
ADT BinaryTree {
数据:
节点集合:{node1, node2, ..., nodeN}
根节点:root
操作:
initTree(): 初始化二叉树
isEmpty(): 判断二叉树是否为空
getRoot(): 获取根节点
getLeft(node): 获取左子节点
getRight(node): 获取右子节点
insertLeft(node, value): 插入左子节点
insertRight(node, value): 插入右子节点
deleteLeft(node): 删除左子树
deleteRight(node): 删除右子树
traverse(mode): 遍历二叉树
}
二叉树的性质
性质1: 在二叉树的第i层上至多有2i-1个结点(i ≥ 1)。
性质2: 深度为k的二叉树至多有2k-1个结点(i ≥ 1)。
性质3: 对任何一个二叉树T,如果其终端结点个数为n0,度为2的节点数为n2,n0 = n2 + 1。
性质4: 具有n个结点的完全二叉树的深度为⌊ log2n ⌋ + 1。
性质5: 如果对一个有n个结点的完全二叉树(其深度为⌊ log2n ⌋ + 1)的结点按层序编号(从第1层到第⌊log2n⌋ + 1层,每层从左至右),则对任一结点i(1 ≤ i ≤ n),有
(1)如果i = 1,则结点i是二叉树的根,无双亲;如果i>1,其双亲PARENT(i)是结点⌊ i/2 ⌋ 。
(2)如果2i > n,则结点i无左孩子(结点i为叶子节点);否则其左孩子LCHILD(i)的结点为2i。
(3)如果2i + 1 > n,则结点i无右孩子,否则其右孩子RCHILD(i)的结点为2i + 1。

特殊形态的二叉树
满二叉树: 一棵树深度为k且有2k-1个结点的二叉树称为满二叉树。满二叉树的特点就是每一层上的节点数都是最大的节点数。

完全二叉树: 对满二叉树进行连续编号,从上到下,从左至右,当一个深度为k的,有n个结点的二叉树,当且仅当其每一个节点都与深度为k的满二叉树中编号从1至n的结点一一对应时,称之为满二叉树。这种树的特点是
(1)叶子结点只可能在层次最大的两层上出现。
(2)对任一结点,若其右分支下的子孙的最大层次为l,则其左分支下的子孙的最大层次必定为l或l + 1。

遍历二叉树
遍历二叉树是指从根节点出发,按照某种次序依次访问二叉树中的所有结点,使得每个结点都被访问一次且仅被访问一次。
先序(根)遍历
根 → 左子树 → 右子树

中序(根)遍历
左子树 → 根 → 右子树

后序(根)遍历
左子树 → 右子树 → 根

层序遍历
按照层次从上到下逐层访问节点,也称为层序遍历。
