dataStructure_图的基本概念和问题
文章目录
基本概念
图Graph
- 由顶点V(vertex)和边E(edge)构成,记图为G(V,E)
- V(G)表示图G中顶点的有限非空集合
- V={ v 1 , v 2 , ⋯ , v n v_1,v_2,\cdots ,v_n v1,v2,⋯,vn}
- |V|表示顶点集合中的顶点个数,即图G的顶点数
- 要求|V|>0,图不可以是
"空图"
- E(G)表示图G中顶点间的边(关系)集合
- E={ ( v i , v j ) ∣ v i , v j ∈ V (v_i,v_j)|v_i,v_j\in V (vi,vj)∣vi,vj∈V}
- |E|表示图G中的边数
- ∣ E ∣ ⩾ 0 |E|\geqslant0 ∣E∣⩾0,图中允许只有点而没有边
有向图:
- 集合中的边是有向边的有限集的图
- 此时边是顶点的有序对 < v t a i l , v h e a d > 简记作 : < v , w > ; v , w ∈ V ; v 是弧尾 , w 是弧头 此时边是顶点的有序对<v_{tail},v_{head}>简记作:<v,w>;v,w\in V;v是弧尾,w是弧头 此时边是顶点的有序对<vtail,vhead>简记作:<v,w>;v,w∈V;v是弧尾,w是弧头
无向图:
- 和有向图相对应,边都是无向边
- 此时边是顶点的有序对 < v , w > 此时边是顶点的有序对<v,w> 此时边是顶点的有序对<v,w>
简单图
- 图中不存在重复边
- 不存在顶点到自身的边
- 数据结构中讨论的是简单图
完全图(简单完全图)
-
含有
n
(
n
−
1
)
2
含有\frac{n(n-1)}{2}
含有2n(n−1)条边的无向图称为完全图(任意两个结点见都有直接边)
- 对于无向图, 边数 ∣ E ∣ 的取值分为 0 ∼ n ( n − 1 ) 2 边数|E|的取值分为0\sim\frac{n(n-1)}{2} 边数∣E∣的取值分为0∼2n(n−1)
- 这个范围在讨论优向完全图的时候解释
有向完全图
- 有向完全图中任意两个结点间都存在方向相反的两条弧
- 可以考察一个图G的任意一个点v
- 点v相关的边有两类:出边和入边
- 显然出边有 n − 1 n-1 n−1条(图G总共有n个结点)
- 其他结点邻接到v的边,也就是v的入边数也是 n − 1 n-1 n−1
- 所有出边形如:
<
v
i
,
v
j
>
,
v
j
∈
D
S
(
即
V
−
{
v
i
}
)
<v_i,v_j>,v_j\in DS(即V-\{v_i\})
<vi,vj>,vj∈DS(即V−{vi})
- 其中 i = 1 , 2 , ⋯ , n i=1,2,\cdots,n i=1,2,⋯,n
- 类似的对V中其他顶点建立所有出边,就是 i = 1 , 2 , ⋯ , n i=1,2,\cdots,n i=1,2,⋯,n的过程
- 这样一来,每个结点都有n-1条出边和入边
- 此时这个图有n(n-1)条有向边,而且是任意两个结点都有一来一往两条边
- 回到无向图,是不去分方向的,因此任意两个结点间的一来一往两条边合并为一条无向边
- 所以无向图最多有 n ( n − 1 ) 2 \frac{n(n-1)}{2} 2n(n−1)条边
子图
-
设图 G ′ = ( V ′ , E ′ ) 和图 G = ( V , E ) 的子图 , 如果 V ′ ⊆ V 并且 E ′ ⊆ E 则 G ′ 是 G 的子图 设图G'=(V',E')和图G=(V,E)的子图,如果V'\subseteq V并且E'\subseteq E \\则G'是G的子图 设图G′=(V′,E′)和图G=(V,E)的子图,如果V′⊆V并且E′⊆E则G′是G的子图
-
特别的 , 在子图的基础上 , 如果子图 G ′ 的顶点集合 V ′ = V , 那么 G ′ 是 G 的生成子图 特别的,在子图的基础上,如果子图G'的顶点集合V'=V,那么G'是G的生成子图 特别的,在子图的基础上,如果子图G′的顶点集合V′=V,那么G′是G的生成子图
连通
- 在无向图中,如果顶点v到顶点w的路径存在,那么v和w是连同的
- 注意,只要求路径存在,而不要求路径的长度为1(直达)
连通图
- 如果图G中的任意两个顶点是连同的,那么图G是连通图
- 否则为非连同图
极大连连通子图(连通分量)
- 无向图中极大连通子图称为连通分量
- 这里的极大指的
- 是连通子图包含尽可能多的边
- 极小连通子图:
- 既要保持图的连通又要使得边数最少(尽可能的少)
- 如果在分配一个点给极大联通子图就会造成连通性被破坏,那么这样的联通子图才是极大联通子图
- 一个图G的联通子图可以有很多,但是极大联通子图的数量就比较有限,但往往也不是唯一的
- 而且不同的极大联通子图具有不一定相等的顶点数;这些极大联通子图都是图G的连通分量
- 这里的极大指的
- 如果一个包含n个顶点的图是连通图,那么这个连通图至少含有n-1条边
- 设顶点集合 V 1 , 刚开始 , V 1 中只有一个点 v 1 V_1,刚开始,V_1中只有一个点v_1 V1,刚开始,V1中只有一个点v1;图G的点分布在 V 1 , V 2 V_1,V2 V1,V2中
- 现在我们往
V
1
V_1
V1里头加点
- 从 V 2 中取出一个点 v i , 加到 V 1 , v i 和 V 1 中已有点任意一点建立边的联系 , 这会产生一条边 从V_2中取出一个点v_i,加到V_1,v_i和V_1中已有点任意一点建立边的联系,这会产生一条边 从V2中取出一个点vi,加到V1,vi和V1中已有点任意一点建立边的联系,这会产生一条边
- 继续操作下去 , 知道 V 2 中的所有点都被接入到 V 1 集合中 , 就构成了一个具有最少边的联通图 继续操作下去,知道V_2中的所有点都被接入到V_1集合中,就构成了一个具有最少边的联通图 继续操作下去,知道V2中的所有点都被接入到V1集合中,就构成了一个具有最少边的联通图
- 这个过程中 i = 1 , 2 , ⋯ , n − 1 这个过程中i=1,2,\cdots,n-1 这个过程中i=1,2,⋯,n−1
- 因此,n个结点的连通图至少含有n-1条边,否则该图是不连通的!!
完全图和连通图问题
最多允许几条边保持不连通?
- 另方面,如果一个含有n个结点的图G想要避免构成连通图,那么最多允许几条边?
- 容易联想到,n个顶点具有最多边的情况是n阶完全图(这肯定是连通图)
- 现在考虑从n阶完全图中去掉尽可能少的边,来构成非连通图
- 我们抓住一个点,将它与其他n-1个点的联系全部去掉,就构成了有尽可能多边的非联通图
- 这个数值就是n-1阶完全图的边数( 1 2 ( n − 1 ) ( n − 2 ) \frac{1}{2}(n-1)(n-2) 21(n−1)(n−2))
多少条边就可以保证连通?
- 如果某个无向图有n个顶点,那么至少需要多少条边,使得该图一定是一个连通图
- 这类问题也是完全图的问题
- 考虑n-1
个结点最多消耗
1
2
(
n
−
1
)
(
n
−
2
)
个结点最多消耗\frac{1}{2}(n-1)(n-2)
个结点最多消耗21(n−1)(n−2)条边
- 这种情况下,剩下的一个顶点将游离于前n-1个顶点,图还是可能不连通
- 但是如果在加上一条边,由于前n-1个顶点间的边已经完全饱和,那么新增的一条边导致n个结点连通起来
- 考虑n-1
个结点最多消耗
1
2
(
n
−
1
)
(
n
−
2
)
个结点最多消耗\frac{1}{2}(n-1)(n-2)
个结点最多消耗21(n−1)(n−2)条边
生成树
连通图的生成树
- 包含图中所有顶点的极小连通子图
- 根据上面的分析,如果连通图的顶点数为n,那么它的生成树含有n-1条边(不多也不少)
- 在生成树中,减去一条边会导致不再连通
- 加上一条边,会导致回路的形成
- 尽管如此,同一个连通图的生成树不一定唯一
- 例如一个环图G,去掉任何一条边即可得到G的一个生成树
- 因此有最小生成树这类算法
非连通图的生成森林
- 非连通图可以从连通分量的角度考察,它们它是由它若干的极大联通子图构成的
- 分别计算连通分量的生成树
- 这些生成树构成生成树森林
强连通(顶点对)
- 在有向图G中,如果一对顶点v,w;v到w以及w到v都有路径,则这两个顶点是强连通的(双向连通的)
- 注意,连通和强连通一样,只要求路径存在,而不要求路径的长度为1(直达)
强连通图
- 如果有向图G中,所有顶点都是强连通的,那么G是强连通图
- 如果我们按照定义去考察一个有向图是否为连通图,可以分别考察每个顶点是否能够到达其他所有顶点
- 这需要 n ∗ ( n − 1 ) n*(n-1) n∗(n−1)次比较
强连通分量
- 有向图中的极大强连通子图称为有向图的强连通分量
至少需要n条边
-
鉴于有向图的有向性,
- 传递性:如果点v能够到达B,B能够到达集合{C}中的任意点,那么认为v可以到达{C}中的任意点(直观)
-
从 n = 1 n=1 n=1开始考虑
-
n:至少需要的条边数
-
1:0
-
2:2(一条边仅单向可达,必须两条)(记现在的两个顶点为a,b)
-
3:?
-
在n=2的规模内,要让三个点(记为c)能够到达a或者b,至少需要从c出发,邻接一条边到a/b
-
另一方面,为了能够让a/b出发能够到达c,也至少要从a/b出发一条边邻接到c
-
即,任意生成树中的每个结点至少有一条出边和一条入边(这是至少的下限)
-
现在想让n个结点有尽可能少的边,可以尝试:
-
复用边:good idea!
-
比如三个点:A–>B–>C
-
其中A–>C的路径就复用了B–>C的路径(BC边)
-
这是传递性的体现;
- 现在,AB,AC,BC,都没问题
- 但是BA,CB,CA不可以
-
为了让C能够到达A,必须在加一条边
-
- 现在CA,BA(B->C->A),CB(C->A->B),都可以
-
-
简单讲,就是路径长度超过1的,都是有复用的成分
-
-
让每个结点上的边的端点(弧头/弧尾尽可能少)
- 仅保留必要的一组弧头/弧尾
-
可以发现
顺序闭环
状结构(或者逆序闭环,总之箭头方向一致)- 可以实现必要的边数实现所有点互通的目的
- 这是容易验证,因为任意顶点数为N的顺序环上的任意结点x沿着顺序环行进,可以遍历所有环内结点
- 这意味着,从任意一个结点x(x可以取环上的任意结点,不失一般性)开始,沿着一个方向行进,总是可以到达环内任意指定的第二个结点y,包括起点本身
-
-
-
小结
- 在无向图中讨论连通性
- 有向图中讨论强连通性
顶点的度
- 在无向图中
- 顶点v的度 T D ( v ) TD(v) TD(v):图G中依附于顶点v的边的条数
- 有向图中
- 入度(In Degree)和出度(Out Degree)之分
- 入度 I D ( v ) ID(v) ID(v)是以顶点v作为有向边的终点(弧头)
- 出度 O D ( v ) OD(v) OD(v)是以顶点v作为有向边的起点(弧尾)
- 入度(In Degree)和出度(Out Degree)之分
相关性质
- 无向图中,n个顶点,e条边的无向图,
∑
i
=
1
n
T
D
(
v
i
)
=
2
e
\sum\limits_{i=1}^{n}TD(v_i)=2e
i=1∑nTD(vi)=2e
- 无向图的全部顶点的度数之和为边数2倍
- 因为,每条边依赖于两个顶点,每一条都会为其两个断点各贡献一度
- 因此,在统计边数的时候,每条边会贡献2度
- 即,总度数是总边数的2倍
- 至于顶点数n,我们不关心
- 即,总度数是总边数的2倍
-
有向图中
T
D
(
v
i
)
=
I
D
(
v
i
)
+
O
D
(
v
i
)
有向图中TD(v_i)=ID(v_i)+OD(v_i)
有向图中TD(vi)=ID(vi)+OD(vi)
- 并且有 ∑ i = 1 n I D ( v i ) = ∑ i = 1 n O D ( v i ) = e 并且有\sum\limits_{i=1}^{n}ID(v_i)=\sum\limits_{i=1}^{n}OD(v_i)=e 并且有i=1∑nID(vi)=i=1∑nOD(vi)=e
- 还是从统计(有向)边的角度考察
- 每个有向边都分别为他的起点顶点贡献一个出度,以及为他的终点顶点贡献一个入度
- 统计所有边,则得到有向图的顶点总入度和总出度相等(都等于边数e)
边的权
- 在一个图中,每条边都可以标注有含义的数值(类似于带权结点);数值称为权值
带全图(网)
- 边上带有权值的图称为带权图或者网
稀疏图&稠密图
- 边数相较于顶点数少的比较明显的图称为稀疏图(模糊概念)
- 当 ∣ E ∣ < ∣ V ∣ log 2 ∣ V ∣ 当|E|<|V|\log_2|V| 当∣E∣<∣V∣log2∣V∣
路径相关
顶点间路径
- 顶点 v p 到顶点 v q 之间的一条路径是序列 : v p , v x 1 , v x 2 , v x 3 , ⋯ v x m , v x q 顶点v_p到顶点v_q之间的一条路径是序列:v_p,v_{x_1},v_{x_2},v_{x_3},\cdots v_{x_m},v_{x_q} 顶点vp到顶点vq之间的一条路径是序列:vp,vx1,vx2,vx3,⋯vxm,vxq
路径长度
- 路径上的边数就是路径长度
回路(环)
- 环是一种特殊路径:起点和终点一致的路径
有环的充分条件
- 顶点数为n,边数大于n-1的图一定带环
- 前面对生成树的边数的分析结论表明,n个结点最多消耗n-1条边而不差生回路(或者重复边)
简单路径
- 路径序列中,顶点不重复出现的路径是简单路径
简单回路
- 如果一个回路(环)只有首尾结点重复,那么称为简单回路
顶点间距离(最短路径)
- 如果顶点u到顶点v存在最短路径,那么这个最短路径的长度就是顶点u,v的距离
- 如果不存在可达路径,则是距离记为无穷远 ∞ \infin ∞
森林/树/图
有向树
- 自定向下构造的树类似的形状
- 其中一个顶点的入度为0(相当于根结点)
- 其余顶点的入度为1
- 出度不做任何限制
树&图
-
树是可空的,但是图是不可空的
-
但从图形上看,树或森林总是有对应的图可以描述
-
森林中的k棵树犹如连通图断开k-1条边一样
-
如果某个无向图对应于一个森林(包含n个顶点/e条边)
-
由树和图的性质
- 树 : n o d e s = e d g e s + 1 树:nodes=edges+1 树:nodes=edges+1
- 森林 : n o d e s i = e d g e s i + 1 ; i = 1 , 2 , ⋯ , k 森林:nodes_i=edges_i+1;i=1,2,\cdots,k 森林:nodesi=edgesi+1;i=1,2,⋯,k
-
n = ∑ i = 1 k n o d e s i e = ∑ i = 1 k e d g e s i n = ∑ i = 1 k ( e d g e s i + 1 ) = ∑ i = 1 k e d g e s i + ∑ i = 1 k 1 = e + k ∗ 1 = e + k n=\sum\limits_{i=1}^{k}nodes_i \\e=\sum\limits_{i=1}^{k}edges_i \\ n=\sum\limits_{i=1}^{k}(edges_i+1) =\sum\limits_{i=1}^{k}edges_i+\sum\limits_{i=1}^{k}1 =e+k*1=e+k n=i=1∑knodesie=i=1∑kedgesin=i=1∑k(edgesi+1)=i=1∑kedgesi+i=1∑k1=e+k∗1=e+k
-
可见森林中的树的棵树 k = n − e 可见森林中的树的棵树k=n-e 可见森林中的树的棵树k=n−e
-
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了