树
树(Tree)是n(n≥0)个结点的有限集。n = 0 时称为空树。
在任意一颗非空树中:
(1)有且仅有一个特定的称为根(Root)的结点;
(2)当 n>1 时,其余结点可分为 m (m>0) 个互不相交的有限集 \(T_1\)、 \(T_2\)、...、 \(T_n\),其中每一个集合本身又是一棵树,并且称为根的子树(SubTree)
结点分类
结点的度:结点拥有的子树 数目
树的度:树内各结点的 度 最大值
叶结点(终端结点):度为0 的结点
分支节点(内部结点 或 非终端结点):度不为0
结点间关系
结点的子树的 根 称为 该结点的 孩子(Child),相应的,该结点称为孩子的双亲(Parent)
同一个双亲的孩子之间互称兄弟(Sibling)
结点的祖先是从根到 该结点所经分支上的所有结点。如:对 H 来说,D、B、A都是它的祖先。
反之,以某结点为根的子树中的任一结点都称为该结点的子孙。如:对 B 来说,D、G、H、I都是它的孙子。
树的其他概念
结点层次(Level)从根开始定义,根为第一层,根的孩子为第二层。
双亲在同一层的结点互为堂兄弟。如:D、E、F为堂兄弟,G、H、I、J也是堂兄弟
树中结点的最大层次称为树的深度(Depth)或高度。
如果将树中结点的各个子树看成从左到右是有次序的,不能互换,则称该树为有序树,否则称为无序树。
m(m≥0)颗互不相交的树的集合,称为森林(Forest)。对于树中每个结点而言,其子树的集合即为森林
树的存储结构
双亲表示法
假设以一组连续空间存储树的结点,同时在每个结点中,附设一个指示器指示其双亲结点在数组中的位置。也就是说,每个结点除了知道自己是谁,还知道它的双亲在哪里。
C语言实现
/*树的双亲表示法 结点结构定义*/
# define MAX_TREE_SIZE 100
typedef int TElemType; /*树结点的数据类型*/
typedef struct PTNode /*结点结构*/
{
TElemType data; /*结点数据*/
int parent; /*双亲位置*/
};
typedef struct
{
PTNode nodes[MAX_TREE_SIZE]; /*结点数组*/
int r, n; /*根的位置和结点树*/
}PTree;
如下图所示:
由于根结点没有双亲结点,所以我们约定根结点的位置域设置为-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),直到parent为-1时,表示找到了树结点的根。 | ||
| 可是,如果我们要知道结点的孩子是什么,就必须遍历整个结构了! |
孩子表示法
把每个结点的孩子结点排列起来,以单链表作存储结构,则n个结点有n个孩子链表,如果是叶子结点则此单链表为空,然后n个头指针又组成一个线性表,采用顺序存储结构,存放在一个一维数组中。
C语言实现
/*树的孩子表示法结构定义*/
#define MAX_TREE_SIZE 100
typedef int TElemType; /*树结点的数据类型*/
typedef struct CTNode /*孩子结点*/
{
int child;
struct CTNode* next;
} *ChildPtr;
typedef struct /*表头结构*/
{
TElemType data;
ChildPtr firstchild;
}CTBox;
typedef struct /*树结构*/
{
CTBox nodes[MAX_TREE_SIZE]; /*结点数组*/
int r, n; /*根的位置和结点数*/
}CTree;
双亲孩子表示法
孩子兄弟表示法
任意一棵树,它的结点的第一个孩子如果存在就是唯一,它的右兄弟如果存在也是唯一的。因此,我们设置两个指针,分别指向该结点的第一个孩子和此结点的右兄弟。
C语言实现
typedef int TElemType; /*树结点的数据类型*/
/*树的孩子兄弟表示法结构定义*/
typedef struct CSNode
{
TElemType data;
struct CSNode* firstchild, * rightsib;
}CSNode, * CSTree;
二叉树
二叉树(Binary Tree)是 n (n≥0)个结点的有限集合,该集合或者为空集(称为空二叉树),或者由一个根结点和两颗互不相交的、分别称为根结点的左子树和右子树的二叉树组成。
二叉树特点
- 每个结点最多有两颗子树,所以二叉树不存在度大于 2 的结点。【注意:不是只有两颗子树,而是最多有;没有子树或只有一颗子树也是可以的】
- 左子树和右子树是有顺序的,不可以任意颠倒。
- 即使树中某结点只有一颗子树,也要区分它是左子树还是右子树。
二叉树具有5中基本形态:
- 空二叉树
- 只有一个根结点
- 根结点只有左子树
- 根结点只有右子树
- 根结点既有左子树又有右子树
特殊二叉树
斜树
所有的结点都是只有左子树的二叉树叫左斜树
所有的结点都是只有右子树的二叉树叫右斜树
左斜树和右斜树统称为斜树
满二叉树
在一棵二叉树中,如果所有分支结点都存在左子树和右子树,并且所有叶子都在同一层上,这样的二叉树称为满二叉树。
完全二叉树
对一棵具有n个结点的二叉树按层序编号,如果编号为i(1≤i≤n)的结点与同样深度的满二叉树中编号为i的结点在二叉树中位置完全相同,则这颗二叉树称为完全二叉树。
二叉树的性质
1、在二叉树的第 i 层上至多有 \(2^{(i-1)}\) 个结点(i≥1)。
2、深度为 k 的二叉树至多有 \(2^{k}-1\) 个结点(K≥1)。
3、对于任何一颗二叉树 T ,如果其终端结点数为 \(n_0\),度为2的结点数为 \(n_2\),则\(n_0 = n_2 + 1\)。
4、具有 n 个结点的完全二叉树的深度为 \(\left \lfloor log_2n \right \rfloor +1\)。(\(\left \lfloor x \right \rfloor\)表示不大于x的最大整数)
参考:
[1]大话数据结构/程杰著.——北京:清华大学出版社,2011.6

浙公网安备 33010602011771号