数据结构与算法(4) - 树

1. 树的定义和基本概念

:n(>= 0)个结点构成的有限集合。
节点的度:节点的子树数目,即有多少子树,该节点的度就是多少。
树的度:所有节点中最大的度数。
叶节点:度为0的节点。
路径和路径长度:节点a到节点b的路径就是二者之间的节点序列,边数为路径长度。
祖先节点:root到某个节点的路径上的所有节点都是该节点的祖先节点。
子孙节点:某个节点的所有子树中的节点都是该节点的子孙节点。
层次:根节点在第一层,往下依次递增。
树的深度(高度):树的层数。

2. 树的特点

子树是不相交的。
除了根节点,每个节点有且仅有一个父节点。
n个结点的树,有n-1条边。
任意两个结点之间有且只有一条路径。

3. 二叉树

树的一种,除叶节点外,每个节点最多只有两个子树。
注意,二叉树中的某个节点,即使只有一个子树,也要区分左右。

3.1 二叉树分类

3.1.1 斜二叉树

每个节点都只有一个左子树 或者 都只有一个右子树,此时,二叉树退化成链表了。

3.1.2 完美二叉树(满二叉树)

除了叶节点,每个节点都有两个子节点,并且所有的叶节点都在同一层

3.1.3 完全二叉树

可以理解为完美(满)二叉树的一种特殊情况,只允许最后一层的右边节点缺失,其他部分必须是满的。
在这里插入图片描述
注意,同样节点个数的各种二叉树中,完全二叉树的深度最小。

3.2 二叉树性质

  1. 第 i 层最多有2i-1个节点
  2. 深度为k的二叉树,最多有2k-1个节点(等比数列前n项和)。
  3. 设度为0节点个数为n0,度为1的节点个数为n1,度为2的节点个数为n2,则有n0=n2+1。

性质3证明:
二叉树节点总数是n0+n1+n2,所以他的边数是n0+n1+n2-1。
度为0的节点向下贡献的边数是 0xn0,度为1的节点向下贡献的边数是 1xn1,度为2的节点向下贡献的边数是 2xn2。
所以有等式 n 0 + n 1 + n 2 − 1 = 0 x n 0 + 1 x n 1 + 2 x n 2 n0+n1+n2-1 = 0xn0 + 1xn1 + 2xn2 n0+n1+n21=0xn0+1xn1+2xn2成立,即可得出性质3的关系式。

  1. 有n个节点的完全二叉树深度为 log(n) + 1向下取整 ,这个可以根据性质2反推出来。
  2. 对于一颗完全二叉树来说,根节点序号为1,则其他节点有如下规律:

若一个节点的序号是 i, 那么他的左子节点序号是 2 * i,右子节点的序号是 2 * i + 1

3.3 二叉树的遍历

先序----根 左 右----递归
中序----左 根 右----递归
后序----左 右 根----递归
层序----从上到下,从左到右----宽度优先搜索

3.3.1 遍历的典型应用

求树的深度
输出所有的叶子节点
由两种遍历的结果确定一颗二叉树(必须要有中序遍历)

3.3 二叉树的顺序存储

用数组,编号从1开始存储(从0开始也可,那么根节点序号和左右节点序号的关系式要稍微改一下)。
这种存储方式对于完全二叉树或者完美二叉树来说比较好,存储空间利用率比较高,如果是一般的二叉树(比较稀疏)用这种方式进行存储就会造成空间浪费。

3.4 二叉树的链式存储

struct Node{
    
    
	int val;
	Node* left;
	Node* right;
}

4. 二叉搜索树

搜索:静态查找、动态查找

4.1 概念

左子的值都比根节点小,右子的值都比右节点大,且左右子树都是二叉搜索树。

4.2 查找(logN)

相当于二分查找,X与根节点的值比较,如果X小于根节点的值,就往左子树去找,若大于,就往右子树去找。

4.2.1 找min和max值

整棵树的最小值一定在最左分支的叶子节点上。
整棵树的最大值一定在最右分支的叶子节点上。

4.3 插入

用习题学习

4.4 删除

用习题学习

5. 平衡二叉树(AVL树)

一个概念:
平衡因子:左子树高度 - 右子树高度
平衡二叉树:树中的任意一个节点的左、右子树高度差绝对值不超过1。

5.1 平衡二叉树的调整

RR旋转

在这里插入图片描述
在这里插入图片描述
图中关注的是“麻烦节点”与“发现节点”之间的位置关系,图上,Nov在Mar右边的右边。具体例子如下:
在这里插入图片描述
在这里插入图片描述

LL旋转

在这里插入图片描述

LR旋转

在这里插入图片描述

LR旋转

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/u014117943/article/details/113477942