一、树:
1.1 概念:
- 树是
n
个结点的有限集合n = 0
时称为空树 - 任何一颗非空树中 有且仅有一个特定的称为根的结点
n > 1
时 ,其余结点可分为m
个 互不相交的有限集合T1、T2、T3...Tm
,其中每个集合本身又是一颗树,并且称为根节点的子树
1.2特点:
- 根节点没有前驱,除根节点外的所有结点有且只有一个前驱
- 树中所有结点可以有零个或者多个后继
1.3属性:
- 结点的层次( 深度 ) :从上往下数
- 结点的高度 :从下往上数
- 树的高度( 深度 ) : 总共多少层
- 结点的度 : 有几个孩子( 分支 )
- 树的度:各结点的度的最大值
- 有序树:树中结点的各子树从左到右是有次序的,不能互换 否则称为无序树
- 森林:m 棵互不相交的树的集合
1.4性质:
-
结点数 = 总度数 + 1
-
度为m的树 VS m叉树
-
度为m的树第i层至多有 m^i-1个结点
也可以是 m叉树的第i层至多有m^i-1个结点
-
高度为h的m叉树至多有
(m^h - 1 ) / (m - 1)
-
高度为 h 的 m 叉树至少有
h
个结点 -
高度为 h 、度为 m 的树至少有
h + m + 1
个结点
-
具有 n 个结点的 m 叉树的最小高度为
二、二叉树:
2.1概念:
二叉树 是 n 个结点的有限集合
- 或者为空二叉树 n = 0
- 或者由一个 根节点 和两个互不相交的被称为根的左子树 和 右子树 组成 ,左子树 和 右子树又分别是一颗二叉树
2.2特点:
- 每个结点至多只有两颗子树
- 左右子树不能颠倒 (二叉树是有序树)
2.3五种状态:
2.4特殊的二叉树:
-
满二叉树
一颗高度为 h 且含有 2^h - 1 个结点的二叉树
特点:
只有最后一层有叶子结点
不存在度为1的结点
按层序从1开始编号,结点i的左孩子 为 2i ,右孩子为 2i+1,结点i的父节点为 i/2 下取整(如果存在)
2. 完全二叉树
当且仅当其每个结点都与高度为h的满二叉树中编号为 1 ~ n 的结点一一对应时称为完全二叉树
特点:
只有最后两层可能有叶子节点
最多只有一个度为1的结点
按层序从1开始编号,结点i的左孩子 为 2i ,右孩子为 2i+1,结点i的父节点为 i/2 下取整(如果存在)
i <= n/2下取整 为 分支节点 i>n/2下取整 为叶子节点
如果某个节点只有一个孩子,那么一定是左孩子 -
二叉排序树
一颗二叉树或者是空二叉树
性质:
左子树上所有节点的关键字均小于根节点的关键字
右子树上所有节点的关键字均大于根结点的关键字
左子树和右子树各是一颗二叉排序树
用于元素的搜索、排序
-
平衡二叉树
树上任一结点的左子树和右子树的深度之差不超过1
2.5二叉树常考性质:
- 设非空二叉树中度为0、1、2的结点个数分别是n0、n1、n2,则n0 = n2 + 1
推导:
n = n0+n1+n2
n = n1+2n2+1 (树的总结点数 = 总度数 + 1)
则可以得出 :n0 = n2 + 1 - 二叉树第i层至多有2i-1个结点( i>=1 )
m叉树第i层至多有mi-1 个结点( i>=1 )
- 高度为h的二叉树至多有2h-1个结点(满二叉树)
高度为h的m叉树至多有 m h − 1 m − 1 \frac{m^h-1}{m-1} m−1mh−1个结点
2.6二叉树的存储结构:
- 顺序存储
10.链式存储
2.7二叉树的遍历(重点):
- 先序遍历:根节点 、左子树、右子树
- 中序遍历:左子树、根节点、右子树
- 后序遍历:左子树、右子树、根节点
- 先序、后序、中序例题分析:
- 求树的深度的应用
2.8二叉树的层序遍历(BFS):
2.9由遍历序列构造二叉树():
关键:找到树的根节点,并根据中序序列划分左右子树,再找到左右子树根节点
结论:若只是给出一颗二叉树的 前\中\后\层 序遍历中的一种,不能唯一确定一颗二叉树
15. 前序 + 中序 遍历序列 构造出二叉树
16. 后序 + 中序 遍历序列
17. 层序 + 中序 遍历序列
2.10线索二叉树(重点):
线索:指向 前驱 / 后继 的指针称为线索
1. 线索二叉树的作用
方便从一个指定节点出发,找到其前驱、后继 方便遍历
2. 线索二叉树的存储结构
普通二叉树存储结构基础上,增加两个标志位:ltag rtag
若无左子树,令 lchild 指向其前驱结点
若无右子树,令 rchild 指向其后继节点
3. 手算画出线索二叉树:
- 确定线索二叉树类型 - 中序、先序、后续
- 按照对应遍历规则,确定各个节点的访问顺序,并写上编号
- 将n+1个空链域连上前驱、后继
4、 二叉树线索化
核心:
- 中序/先序/后续遍历算法的改造 当访问一个结点时,连接该节点与前驱结点的线索信息
-用一个pre指针记录当前访问结点的前驱结点
易错点: - 最后一个结点的 rchild、lchild 的处理
- 先序线索化中 Itlag ==0 时才可以对左子树先序线索化 否则死循环
中序线索化
先序线索化
后续线索化
5、 线索二叉树找 前驱、后继
-
中序线索二叉树找中序后继、中序前驱
-
先序线索二叉树找先序后继、前驱
-
后序线索二叉树找后续前驱、后继
三、树的存储结构:
3.1双亲表示法(顺序存储)
每个结点中保存指向双亲的 ” 指针 “
优点:找父节点方便 缺点:找孩子不方便
3.2 孩子表示法(顺序 + 链式存储)
顺序存储每个节点,每个节点中保存孩子链表头指针
优点:找孩子方便 缺点:找父节点不方便
3.3 孩子兄弟表示法(链式存储)(重点)
二叉链表存储树
左孩子 右兄弟
3.4 森林 和 二叉树 的转换
森林:m棵互不相交的树的集合
森林中各个树的根节点之间互为兄弟关系
3.5 树 和 森林 的遍历
3.5.1 树 的先根遍历
树的先根遍历序列 和这棵树对应的二叉树的先序遍历序列相同
3.5.2 树 的后根遍历
3.5.3 树 的层次遍历
3.5.4 森林的先序遍历
每棵树去掉根节点之后,各个子树又组成森林
同样也等同于对二叉树的先序遍历(先将森林转为二叉树)
3.5.5 森林的中序遍历
等同于依次对各个树进行后根遍历
也等同于转为二叉树的中序遍历
四、二叉排序树(BST):
4.1定义
又称二叉查找树 BST
左子树上所有节点的关键字均小于根节点的关键字
右子树上所有节点的关键字均大于根节点的关键字
左子树 和 右子树 又各是一颗二叉排序树
左子树节点值 < 根节点 < 右子树节点值
进行中序遍历,可以得到一个递增的有序序列
4.2 二叉排序树的查找
非递归实现:复杂度O(1)
递归实现:(复杂度O(h))
4.3 二叉排序树的插入
4.4 二叉排序树的构造
4.5 二叉排序树的删除
- 情况1
- 情况2
- 情况3
4.6 二叉排序树的查找效率分析
取决于树的高度:最好O(log n) 最坏 :O(n)
查找长度:查找运算中,需要对比关键字的次数称为查找长度
平均查找长度 ASL
五、平衡二叉树 ( AVL树 ):
5.1 平衡二叉树的定义
树上任一结点的左子树 和 右子树的高度之差不超过 1
结点的平衡因子 = 左子树高 - 右子树高
平衡二叉树结点的平衡因子的值只能是 -1 、0、1
5.2 平衡二叉树的插入
每次调整的对象都是最小不平衡子树
- LL
- RR
- LL 和 RR 代码思路
- LR
- RL
- 练习
5.3 平衡二叉树的查找效率分析
假设以Nh表示深度为h的平衡二叉树中含有的额最少结点数
则N0=0,N1=1,N2 = 2;
并且:Nh = Nh-1 + Nh-2 + 1
含有n个结点的平衡二叉树的最大深度是O(log2N)
平衡二叉树平均查找长度为O(logN2N)
5.4 平衡二叉树的总结
六、哈夫曼树:
6.1 概念
结点的权:
结点的带权路径长度:从树的根到该结点的路径长度(经过的边数) 与 该结点上权值的乘积
树的带权路径长度:树中所有叶节点的带权路径长度之和 WPL=
∑
i
=
1
n
.
\sum_{i=1}^n .
∑i=1n.Wi * Li
哈夫曼树:在含有n个带权叶结点的二叉树中,其中带权路径长最小的二叉树称为哈夫曼树,也称最优二叉树
6.2 哈夫曼树的构造
6.3 哈夫曼编码
前缀编码:若没有一个编码是另一个编码的前缀则称为前缀编码
哈夫曼编码:字符集中每个字符作为一个叶子结点,各个字符出现的频度作为结点的权值, 用哈夫曼树的构造方法构造哈夫曼树
哈夫曼树不唯一