前面我们已经提到了线性表,栈,队列等数据结构,他们有一个共同的特性,就是结构中每一个元素都是一对一的,可是在现实中,还有很多一对多的情况需要处理,所以我们需要研究这种一对多的数据结构 —— 树,并运用它的特性来解决我们在编程中遇到的问题。

一、树的定义

  1,树Tree是n(n >= 0) 个结点的有限集。n = 0时称为空树  在任意一棵非空的树中,

  (1)有且仅有一个特定的根结点

  (2)当n>1时,其余节点可分为m(m > 0)个互不相交的有限集T1,T2,.....,Tm,其中每一个集合又是一棵树,并且称为根的子树。如下图所示

 

注意:1,根节点是唯一的    2,子树的个数没有限制,但它们一定是互不相交的

2,结点分类

 

  (1)结点包含一个数据元素以及若干指向其子树的分支。

  (2)结点拥有的子树数量称为结点的度

  (3)度为0的结点称为叶节点或终端节点

  (4)度不为0的结点称为非终端结点或分支结点

  (5)一棵树的度是树内各节点的度的最大值

3,结点间的关系

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

4,树的其他相关概念

  (1)结点的层次从根开始定义,根为第一层,根的孩子为第二层,以此类推。

  (2)其双亲在同一层的结点互为表兄弟

  (3)树中结点的最大层次称为树的深度或高度

  (4)如果将树中结点的各子树看成从左至右是有次序的,不能互换的,则称该树为有序树,否则称为无序树。

  (5)森林是m(m >= 0)棵互不相交的树的集合

二、树的存储结构

  我们介绍三种不同的表示方法:双亲表示法、孩子表示法、孩子兄弟表示法。

  1,双亲表示法

  结点可能没有孩子,但一定有双亲。假设我们以一组连续空间存储树的结点,同时在每个结点中,附设一个指示器指示其双亲结点在数组中的位置。由于根节点没有双亲,所以我们约定根节点的位置域设为-1.下面是示例

下标 data parent
0 A -1
1 B 0
2 C 0
3 D 1
4 E 2
5 F 2
6 G 3
7 H 3
8 I 3
9 J 4

这样的存储结构,我们可以根据结点的parent指针很容易找到双亲,时间复杂度O(1)。但如果我们要知道结点的孩子呢?对不起,请遍历整个结构才行。那么能不能改进一下呢?

我们增加一个结点最左边孩子的域,不妨叫他长子域,这样很容易得到结点的孩子。如果没有孩子的叶结点,这个长子域就设为-1,如下表

下标 data parent firstchild
0 A -1 1
1 B 0 3
2 C 0 4
3 D 1 6
4 E 2 9
5 F 2 -1
6