Loading


返回 我的技术栈(Technology Stack)



树(Tree)是n(n≥0)个结点的有限集。n = 0 时称为空树。
在任意一颗非空树中:
(1)有且仅有一个特定的称为根(Root)的结点;
(2)当 n>1 时,其余结点可分为 m (m>0) 个互不相交的有限集 \(T_1\)\(T_2\)、...、 \(T_n\),其中每一个集合本身又是一棵树,并且称为根的子树(SubTree)

image


结点分类

结点的度结点拥有的子树 数目
树的度树内各结点的 度 最大值

叶结点(终端结点)度为0 的结点
分支节点(内部结点 或 非终端结点):度不为0
image


结点间关系

结点的子树的 根 称为 该结点的 孩子(Child),相应的,该结点称为孩子的双亲(Parent)
同一个双亲的孩子之间互称兄弟(Sibling)

结点的祖先是从根到 该结点所经分支上的所有结点。如:对 H 来说,D、B、A都是它的祖先。
反之,以某结点为根的子树中的任一结点都称为该结点的子孙。如:对 B 来说,D、G、H、I都是它的孙子。

image


树的其他概念

结点层次(Level)从根开始定义,根为第一层,根的孩子为第二层。
双亲在同一层的结点互为堂兄弟。如:D、E、F为堂兄弟,G、H、I、J也是堂兄弟
树中结点的最大层次称为树的深度(Depth)或高度。

image

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

m(m≥0)颗互不相交的树的集合,称为森林(Forest)。对于树中每个结点而言,其子树的集合即为森林


树的存储结构

双亲表示法

假设以一组连续空间存储树的结点,同时在每个结点中,附设一个指示器指示其双亲结点在数组中的位置。也就是说,每个结点除了知道自己是谁,还知道它的双亲在哪里。

C语言实现

image

/*树的双亲表示法 结点结构定义*/
# 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。

image

下标 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个头指针又组成一个线性表,采用顺序存储结构,存放在一个一维数组中。
image

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;

双亲孩子表示法

image

孩子兄弟表示法

任意一棵树,它的结点的第一个孩子如果存在就是唯一,它的右兄弟如果存在也是唯一的。因此,我们设置两个指针,分别指向该结点的第一个孩子和此结点的右兄弟。
image

C语言实现

typedef int TElemType; /*树结点的数据类型*/
/*树的孩子兄弟表示法结构定义*/
typedef struct CSNode
{
	TElemType data;
	struct CSNode* firstchild, * rightsib;
}CSNode, * CSTree;

image


二叉树

二叉树(Binary Tree)是 n (n≥0)个结点的有限集合,该集合或者为空集(称为空二叉树),或者由一个根结点和两颗互不相交的、分别称为根结点的左子树和右子树的二叉树组成。
image

二叉树特点

  • 每个结点最多有两颗子树,所以二叉树不存在度大于 2 的结点。【注意:不是只有两颗子树,而是最多有;没有子树或只有一颗子树也是可以的】
  • 左子树和右子树是有顺序的,不可以任意颠倒。
  • 即使树中某结点只有一颗子树,也要区分它是左子树还是右子树。

image

二叉树具有5中基本形态:

  • 空二叉树
  • 只有一个根结点
  • 根结点只有左子树
  • 根结点只有右子树
  • 根结点既有左子树又有右子树

特殊二叉树

斜树

所有的结点都是只有左子树的二叉树叫左斜树
所有的结点都是只有右子树的二叉树叫右斜树
左斜树和右斜树统称为斜树
image

满二叉树

在一棵二叉树中,如果所有分支结点都存在左子树和右子树,并且所有叶子都在同一层上,这样的二叉树称为满二叉树
image

完全二叉树

对一棵具有n个结点的二叉树按层序编号,如果编号为i(1≤i≤n)的结点与同样深度的满二叉树中编号为i的结点在二叉树中位置完全相同,则这颗二叉树称为完全二叉树

image


二叉树的性质

1、在二叉树的第 i 层上至多有 \(2^{(i-1)}\) 个结点(i≥1)。
image
2、深度为 k 的二叉树至多有 \(2^{k}-1\) 个结点(K≥1)。
image
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


posted @ 2021-08-12 11:16  言非  阅读(59)  评论(0)    收藏  举报