二叉树的线索化:
线索二叉树找前驱/后继
根据已经构建出来的线索二叉树 找到一个节点的后序或者前驱
使用中序线索二叉树进行中序遍历 (利用线索实现非递归算法 空间复杂度度为O(1))
思路 :使用一个for循环 p的初值是以t为根节点找到最左边的子树 每循环一次就让p等于中序的下一个节点 直到p=null
使用中序线索二叉树进行逆向中序遍历
使用for循环 第一个找到当前根节点的最右边的节点 然后找它的中序前驱
先序线索二叉树找先序后继
如果p有左孩子 则p的先序后继为左孩子 如果没有左孩子 先序后继为右孩子
先序线索二叉树找先序前驱
先序遍历中 左右子树中的结点只可能是根的后继不可能是前驱 所以给定一个结点 如果按照之前的方法只能用土办法从头开始先序遍历
改用三叉链表可以找到父节点 三叉链表就是多一个指向父节点的指针
如果当前结点是左子树 那么先序的前驱是他的父节点
如果当前的结点是右子树 且当前的父节点没有左子树 那么先序前驱就是父节点
如果当前的结点是右子树 且当前的父节点有左子树 根左右 那么先序前驱是父节点的左子树中最后一个被先序遍历的结点
如果p是根节点 则p没有先序前驱
假设有右孩子
后序线索二叉树的后序前驱就是右孩子
假设没有右孩子
一定有左孩子 后序线索二叉树的后序前驱就是左孩子
如果当前的结点是右孩子 后序后继就是父节点
如果当前结点是左孩子 且父节点没有右孩子 后序后继就是父节点
如果当前的结点是左孩子 且父节点有右孩子 后序后继就是以右孩子为根节点的后序遍历的第一个结点
树 的存储结构
概览
使用双亲表示法:用数组顺序存储各个结点 每个结点中保存数据元素,指向双亲结点(父节点的指针)即存放父元素在数组中的下标
也可以用这个方法存储森林 让根节点存储的下标为-1即可 即它不指向任何的父元素
优缺点 找父元素方便 找孩子不方便
使用孩子表示法: 用数组顺序存储各个结点 每个结点中保存数据元素,孩子链表头指针 ,即数组中的每个元素由数据元素和一个链表组成 链表中每个结点内容是孩子结点在数组中的位置 以及下一个孩子的指针
优缺点 找孩子方标 缺点 找双亲结点不方便
使用孩子兄弟表示法
数据结构和二叉树类似 采用二叉链表实现 每个结点内保存数据元素和两个指针 区别在于左指针存储左孩子 右指针存储右兄弟结点
树森林与二叉树的转换
树转二叉树 森林转二叉树 技巧就是想象把整棵树提起来
二叉树转树 二叉树转森林 技巧就是根据层序每层恢复
树 森林的遍历
树的遍历
森林的遍历
树的先根遍历: 若树非空 先访问根节点 再依次(使用while循环) 对每棵子树进行先根遍历
树的先根遍历序列与这颗二叉树的先序序列相同
树的后根遍历: 若树非空 先依次(使用while循环) 对每棵子树进行后根遍历 再访问根节点
树的后根遍历序列与这颗二叉树的中序序列相同
层序遍历:和二叉树的层序遍历一样
森林的遍历 : 先序遍历等同于依次对二叉树的先序遍历 树的先根遍历
中序等同于依次对二叉树的中序遍历 树的后跟遍历
哈夫曼树
在含有n个带权叶节点的二叉树中 其中带权路径长度(wpl)最小的二叉树 称为哈夫曼树 也叫最优二叉树
并查集
就是使用双亲表示法存储树或者森林
涉及两种操作
并查集的终极优化
压缩路径: find 操作 先找到根节点 再将查找路径上的所有结点都挂到根节点下
每次find操作 先找到根 再压缩路径 可使树的高度不超过O(α(n)) α(n)是一个增长很缓慢的函数
不超过4
目标
图的概念
图G由顶点集V和边集E组成,记为G = (V, E),其中V(G)表示图G中顶点的有限非空集;E(G)
表示图G中顶点之间的关系(边)集合。若V = {v1, v2, … , vn},则用|V|表示图G中顶点的个数,也称图G的阶,E = {(u, v) | uÎV, vÎV},用|E|表示图G中边的条数
注意:线性表可以是空表,树可以是空树,但图不可以是空,即V一定是非空集
对于无向图 顶点的度指得是依附于该顶点的边的条数 一个边会被计算两次 所以即无向图的全部顶点的度的和等于边数的2倍
对于有向图 顶点的度等于入度和出度之和
在有n个顶点 e条边的有向图中 入读之和=出度之和=e
要搞清楚一些概念:
路径: 顶点1到顶点n之间的顶点序列
回路: 第一个顶点和最后一个顶点相同的路径
简单路径: 一个顶点不重复出现
简单回路:除了第一个顶点和最后一个顶点之外其他的顶点不重复出现
路径长度: 路径上变得数目
点到点的距离: 存在路径就是路径长度 不存在就是无穷
无向图点和点有路径: 则称点之间是联通的
有向图中点和点双向都有路径: 两个顶点式强连通的
无向图:
连通图至少有n-1条边
如果是计算非连通最多的边数
可以先想象让一个顶点孤立出来 剩下n-1条边全部连满
有向图
强连通图至少有n条边 形成回路
子图和生成子图
子图就是原来图的一部分顶点 和一部分边 但是只要子图包括了边 就要把这条边的所有顶点加进来
生成子图 顶点集合和原图完全一模一样,只允许删边,不能删顶点。
对比普通子图:普通子图可以删顶点;生成子图严禁删顶点,仅删边。
例子:生成树,就是连通无向图的一个生成子图,并且恰好 条边、连通、无环。
无向图中的极大连通子图称为连通分量
子图必须连通,且包含尽可能多的顶点和边 意思是这个无向图本身可以是非连通的
性质:
连通分量一定是连通子图,但连通子图不一定是连通分量。 连通子图只要是连通的子图就行
一句话:只要还能把外面顶点吸进来并且保持连通,那它就不是连通分量。
有向图中的极大强连通子图称为有向图的强连通分量
定义:极大强连通子图 = 强连通分量
生成树和生成森林
定义:连通图的生成树,是包含全部顶点的一个极小连通子图
一、生成树(连通无向图)
定义:连通图的生成树,是包含全部顶点的一个极小连通子图
极小连通子图:想要保持连通,边已经少到不能再少。少任意一条边就不再连通。
n 个顶点的生成树:严格只有 条边。两个核心性质(选择题高频)
删除生成树任意 1 条边 → 图不再连通。
往生成树上任意加 1 条原图的边 → 必然产生回路 (环)
生成树不是唯一的
二、生成森林(非连通无向图)
定义:非连通图,每个连通分量各自取一棵生成树,组合在一起,整体就是生成森林。
假设原图 n 个顶点,一共有 k 个连通分量。
每个连通分量顶点数 ,
每个分量生成树边数:
总边数:
带权值
几种特殊形态的图
2)有向完全图
任意一对顶点:同时存在两条方向相反的弧 ,。n 个顶点:总边数
。边范围:。
稀疏图 & 稠密图
稀疏图:边的数量很少;一般判定标准:。适合邻接表存储。
稠密图:边数量很多,接近完全图。适合邻接矩阵存储
树——不存在回路,且连通的无向图
有向树——一个顶点的入度为0、其余顶点的入度均为1的有向图,称为有向树(边方向一般从根向外。我们数据结构学的普通树,存储画出来就是这种有向树)
配套公式速记卡
n 顶点连通无向图生成树:边数 =
n 顶点,k 个连通分量,生成森林边数 =
n 顶点无向完全图边数:
n 顶点有向完全图边数:
n 顶点无向树:连通 + 无环 + 条边;边 > n‑1 必有环。