1.树的定义
树(Tree)是n(n≥0)个有限数据元素的集合。当n=0 时,称这棵树为空树。在一棵非树T 中:
(1)有一个特殊的数据元素称为树的根结点,根结点没有前驱结点。
(2)若n>1,除根结点之外的其余数据元素被分成m(m>0)个互不相交的集合T1,T2,…,Tm,其中每一个集合Ti(1≤i≤m)本身又是一棵树。树T1,T2,…,Tm 称为这个根结点的子树。
可以看出,树是一种一对多的概念,在树的定义中用了递归概念,即用树来定义树。因此,树结构的算法类同于二叉树结构的算法,也可以使用递归方法。
树的定义还可形式化的描述为二元组的形式:
当树为空树时,D=Φ;当树T 不为空树时有:
树定义的形式化,主要用于树的理论描述。
图7.1(a)是一棵具有9 个结点的树,即T={A,B,C,…,H,I},结点A 为树T 的根结点,除根结点A 之外的其余结点分为两个不相交的集合: T1={B,D,E,F,H,I}和T2={C,G},T1 和T2 构成了结点A 的两棵子树,T1 和T2 本身也分别是一棵树。例如,子树T1 的根结点为B,其余结点又分为两个不相交的集合:T11={D},T12={E,H,I}和T13={F}。
T11、T12 和T13 构成了子树T1 的根结点B 的三棵子树。如此可继续向下分为更小的子树,直到每棵子树只有一个根结点为止。
从树的定义和图7.1(a)的示例可以看出,树具有下面两个特点:
(1)树的根结点没有前驱结点,除根结点之外的所有结点有且只有一个前驱结点。
(2)树中所有结点可以有零个或多个后继结点。
由此特点可知,图7.1(b)、(c)、(d)所示的都不是树结构(互不相交)。

2.树的储存结构
储存结构分为顺序储存结构和链式储存结构。
顺序储存结构是用一段连续的地址储存数据元素,一般通过数组表示。
链式储存结构是通过指针来链接到下一个元素。
对于树的表示需要结合两者。
一双亲表示法
我们以一组连续的空间储存树的节点,同时在节点中附带一个指示器标示双亲在链表中的位置。
这种储存结构的好处是,我们能够很容易的找到一个节点的父节点,O(1),但是想找到一个节点的子节点需要遍历整个链表。
二孩子表示法
每个节点有多个指针域分别指向一颗子树的根节点。我们把它叫做多重链表表示法。
但是每个节点的度是不一样,给这种表示法带来了一定的困难。
有两种方案解决这个问题:
第一种,指针域的个数等于树的度,即各个节点度的最大值。
第二种,每个节点指针域的个数等于该节点的度,并设立一个专门的域来保存节点的度。
第一种方法对于树中度差别很大的情况下极度的浪费了空间。
第二种方法虽然克服了浪费空间的问题,但是各个链表的长度不一样,这给操作带来一定的困难。
这就引出了我们的孩子表示法。
每个节点的孩子节点以单链表的形式储存起来,n个头指针又组成一个链表,以顺序表示法储存起来。
三孩子兄弟表示法
任意一棵树,它的节点的第一个孩子节点存在一定是唯一的,它的右兄弟节点存在也一定是唯一的。
我们可以对任意一棵树进行改造,它很容易的把任意棵树变成二叉树。