From aa7bee8970457f79eedc19a2e89db27a874b5d76 Mon Sep 17 00:00:00 2001 From: Didnelpsun <2675350965@qq.com> Date: Sat, 5 Nov 2022 23:23:50 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Data-Structrue/6-tree.md | 44 ++++++++++++++++++++++++++++++++------- Data-Structrue/7-graph.md | 6 +++++- 2 files changed, 41 insertions(+), 9 deletions(-) diff --git a/Data-Structrue/6-tree.md b/Data-Structrue/6-tree.md index 785a143..c632a4a 100644 --- a/Data-Structrue/6-tree.md +++ b/Data-Structrue/6-tree.md @@ -132,6 +132,8 @@ 先序遍历的第一个结点一定是二叉树根结点。中序遍历中根结点必然将序列分为两个部分,前一个序列是左子树的中序序列,后一个序列是右子树的中序序列。同理先序序列中子序列的第一个结点就是左右子树的根结点。 +根据二叉树前序遍历和中序遍历的递归算法中递归工作栈的状态变化得出:前序序列和中序序列的关系相当于以前序序列为入栈次序,以中序序列为出栈次序。因为前序序列和中序序列可以唯一地确定一棵二叉树,所以对于先序遍历的$n$个元素,可以确定卡特兰数$\dfrac{1}{n+1}C_{2n}^n$个二叉树。 + #### 后序+中序 后序:左+根+右;中序:左+根+右。所以根据三个部分对应相同可以推出。 @@ -345,10 +347,6 @@ 用数组元素的下标表示元素名,用根结点的下标表示子合集名,根节点的双亲结点为负数。 -查找,查找两个元素是否属于同一个集合。 - -合并,如果两个元素不属于同一个集合,且所在的两个集合互不相交,则合并这两个集合。 - #### 存储结构 如子集$S_1=\{A,B,D,E\}$、$S_2=\{C,H\}$、$S_3=\{F,G,I\}$。 @@ -358,13 +356,43 @@ 数据元素|A|B|C|D|E|F|G|H|I :----:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-: 数组下标|0|1|2|3|4|5|6|7|8 -双亲|-1|0|-1|0|3|-1|5|2|5 +双亲|-4|0|-2|0|3|-3|5|2|5 -#### 时间复杂度 +其中为负数表示这个点有子结点,其绝对值为孩子数量,为正数表示其父结点的索引值。 -判断两个元素是否属于同一集合只需要找到其根节点进行比较。 +#### 查找 -查的时间复杂度为$O(n)$,并的时间复杂度为$O(1)$。 +查找两个元素是否属于同一个集合。 + +判断两个元素是否属于同一集合只需要找到其根节点进行比较。需要通过递归的方式不断查找父结点。 + +查的时间复杂度为$O(n)$ + +#### 合并 + +如果两个元素不属于同一个集合,且所在的两个集合互不相交,则合并这两个集合。 + +并的时间复杂度为$O(1)$。 + +#### 路径压缩 + +用于提高并查集效率。 + +如果一个结点只有一个子结点,且子结点也只有一个子结点,那么这条链路会非常长,即对应的树的树高会很大,影响查询效率。 + +所以把沿途的结点的父结点都设为最上面的根节点即可,不用一层层查询了。 + +#### 按秩合并 + +并查集经过路径压缩优化之后,并查集并不是是只有两层的一颗树。因为路径压缩只在查找的时候进行,也只压缩一条路径,所有并查集的最终结构仍然可能是比较复杂的。 + +在将一个新元素并入并查集前,就应该使用按秩合并的方式对并查集进行优化。 + +为了避免加深树高,所以新的结点应该合并到矮的子树上。 + +为了降低树的结点数和合并操作的难度,应该将简单的树合并到复杂的树上。 + +用秩数组来记录每个根结点对应的树的深度(如果不是根结点,则秩数组中的元素大小表示的是以当前结点作为根结点的子树的深度);一开始,把所有元素的秩值设为1,即自己就为一颗树,且深度为1;合并的时候,比较两个根结点,把秩值较小者合并到较大者中去。 #### 应用 diff --git a/Data-Structrue/7-graph.md b/Data-Structrue/7-graph.md index 83b675f..8e75eac 100644 --- a/Data-Structrue/7-graph.md +++ b/Data-Structrue/7-graph.md @@ -62,7 +62,7 @@ + 强连通:在有向图中,若从顶点$v$到顶点$u$和从顶点$u$到顶点$v$之间都有**路径**(而不是弧),则称$uv$是强连通。 + 连通图:无向图中任意两个顶点之间都是连通的。 + 强连通图:有向图中任意两个顶点之间都是强连通的。 -+ 子图:设有两个图$G=(V,E)$和$G'=(V',E')$,若$V'$是$V$的子集,$E'$是$E$的子集,则$G'$是$G$的子图。 ++ 子图:设有两个图$G=(V,E)$和$G'=(V',E')$,若$V'$是$V$的子集,$E'$是$E$的子集,则$G'$是$G$的子图。但是不是所有的子集都能构成子图,必须满足原图的关系的子集才行,即存在$\varphi'\in\varphi$(如原图中一条边的两个端点子图的点集中没有,则这个图不是子图)。 + 生成子图:若有满足$V(G')=V(G)$的子图$G'$,则$G'$是$G$的生成子图。(即子图包含所有顶点,但不一定包含所有的边) + 连通分量:无向图$G$中的极大连通子图称为$G$的连通分量;对任何连通图而言,连通分量就是其自身。 + 强连通分量:有向图$G$中的极大连通子图称为$G$的强连通分量;对任何强连通图而言,强连通分量就是其自身。 @@ -148,6 +148,10 @@ + 邻接矩阵存储图,很容易确定图中任意两个顶点之间是否有边相连,时间复杂度为$O(1)$。但是,要确定图中有多少条边,则必须按行、按列对每个元紊进行检测,所花费的时间代价很大。 + 给定顶点找到其邻边要扫描一行,时间复杂度为$O(\vert V\vert)$。 +数学性质: + ++ 设图$G$的邻接矩阵为$A$,$A^n$的元素$A^n[i][j]$表示由顶点$i$到顶点$j$长度为$n$的路径数量。 + 设图$G$的邻接矩阵为$A$,矩阵元素为$0$或$1$,则$A^n$的元素$A^n[i][j]$表示由顶点$v_{i+1}$到顶点$v_{j+1}$的长度为$n$的路径的数目。 邻接矩阵的表示方式是唯一的。