自学内容网 自学内容网

图论理论基础和存储方式的实现

图论1

图论 (Graph theory) 是数学的一个分支,图是图论的主要研究对象。图 (Graph) 是由若干给定的顶点及连接两顶点的边所构成的图形,这种图形通常用来描述某些事物之间的某种特定关系。顶点用于代表事物,连接两顶点的边则用于表示两个事物间具有这种关系。

1、图的理论基础

图(Graph)

​ 用大写字母(如 G G G)表示图,通常记为 G = ( V , E ) G=(V,E) G=(V,E),其中 V V V 表示顶点集, E E E 表示边集。例如:设 G = ( V , E ) G=(V,E) G=(V,E) 是一个无向图, V V V 包含多个顶点, E E E 包含连接这些顶点的边。

相邻(Adjacent)

​ 若顶点 u u u v v v 相邻,可表示为: u ∼ v u \sim v uv。例如:在图 G G G 中,若顶点 u u u v v v 之间有边相连,则有 u ∼ v u \sim v uv

简单图(Simple Graph)

​ 设 G = ( V , E ) G=(V,E) G=(V,E) 为简单图,特点是不存在自环(即不存在边 e = ( u , u ) e=(u,u) e=(u,u) u ∈ V u\in V uV)和多重边(任意两顶点间不存在多条相同边),可描述为: G = ( V , E ) G=(V,E) G=(V,E) 是简单图,满足无自环与多重边条件。

度数(Degree)

  • 无向图中顶点度数:无向图里顶点 v v v 的度数用 deg ⁡ ( v ) \deg(v) deg(v) 表示,比如:在无向图 G G G 中,顶点 v v v 的度数记为 deg ⁡ ( v ) \deg(v) deg(v),其值等于与 v v v 相连的边的数量。

  • 有向图中顶点度数:有向图中顶点 v v v 的入度表示为 indeg ( v ) \text{indeg}(v) indeg(v),出度表示为 outdeg ( v ) \text{outdeg}(v) outdeg(v)。例如:在有向图 G G G 中,顶点 v v v 的入度为 indeg ( v ) \text{indeg}(v) indeg(v),出度为 outdeg ( v ) \text{outdeg}(v) outdeg(v),度数可结合二者考量。

路径(Path)

​ 用 P = ( v 0 , v 1 , ⋯   , v n ) P=(v_0,v_1,\cdots,v_n) P=(v0,v1,,vn) 表示从顶点 v 0 v_0 v0 出发,依次经过 v 1 , ⋯   , v n v_1,\cdots,v_n v1,,vn 这些顶点的路径。例如:在图 G G G 中,存在路径 P = ( v 1 , v 2 , v 3 ) P=(v_1,v_2,v_3) P=(v1,v2,v3),即从顶点 v 1 v_1 v1 出发,依次经过 v 2 v_2 v2 v 3 v_3 v3 的路线。

子图(Subgraph)

设 $G=(V,E)$ 是原图,$G'=(V',E')$ 是它的子图,关系表示为:$V'\subseteq V$ 且 $E'\subseteq E$,同时 $E'$ 中边的端点都在 $V'$ 中,则 $G'=(V',E')$ 为 $G$ 的子图。

​ 比如:已知图 G = ( V , E ) G=(V,E) G=(V,E),取 V ′ V' V V V V 的部分顶点集, E ′ E' E 为相应连接这些顶点的部分边集,满足条件后, G ′ = ( V ′ , E ′ ) G'=(V',E') G=(V,E) 就是 G G G 的子图。

连通(Connected)

  • 无向图连通:设 G = ( V , E ) G=(V,E) G=(V,E) 为无向图,若对任意 u , v ∈ V u,v\in V u,vV,都存在一条路径连接 u u u v v v,则称 G G G 是连通的,可写成: ∀ u , v ∈ V \forall u,v\in V u,vV,存在路径连接 u u u v v v,则 G G G 连通。

  • 有向图连通相关(强连通和弱连通)

    • 强连通:对于有向图 G = ( V , E ) G=(V,E) G=(V,E),若对任意 u , v ∈ V u,v\in V u,vV,都存在从 u u u v v v 的有向路径以及从 v v v u u u 的有向路径,则 G G G 是强连通的,即: ∀ u , v ∈ V \forall u,v\in V u,vV,存在从 u u u v v v 及从 v v v u u u 的有向路径,则 G G G 强连通。

    • 弱连通:若把有向图 G = ( V , E ) G=(V,E) G=(V,E) 的边看作无向边时图是连通的,则 G G G 是弱连通的,表示为:将有向图 G = ( V , E ) G=(V,E) G=(V,E) 的边视为无向边时图连通,则 G G G 弱连通。

无向图(Undirected Graph)

直接用 $G=(V,E)$ 表示无向图,并说明其边无方向特点。

​ 如: G = ( V , E ) G=(V,E) G=(V,E) 为无向图,其边没有方向,即对边 e = ( u , v ) ∈ E e=(u,v)\in E e=(u,v)E u u u v v v 的关系是对称的。

有向图(Directed Graph)

​ 用 G = ( V , E ) G=(V,E) G=(V,E) 表示有向图,强调边有方向。

​ 例如: G = ( V , E ) G=(V,E) G=(V,E) 为有向图,边 e = ( u , v ) ∈ E e=(u,v)\in E e=(u,v)E 有方向,从 u u u 指向 v v v,表示一种单向关系。

割(Cut)

  • 边割(针对无向图):设 G = ( V , E ) G=(V,E) G=(V,E) 是连通无向图,若存在边子集 E ′ ⊆ E E'\subseteq E EE,去掉 E ′ E' E 后使得图不再连通,则 E ′ E' E G G G 的一个边割,可表示为: G = ( V , E ) G=(V,E) G=(V,E) 连通无向图, ∃ E ′ ⊆ E \exists E'\subseteq E EE,去掉 E ′ E' E G G G 不连通,则 E ′ E' E G G G 的边割。

  • 点割(针对无向图):对于连通无向图 G = ( V , E ) G=(V,E) G=(V,E),若存在顶点子集 V ′ ⊆ V V'\subseteq V VV,去掉 V ′ V' V 以及和这些顶点相关联的边后使得图不再连通,则 V ′ V' V G G G 的一个点割,写成: G = ( V , E ) G=(V,E) G=(V,E) 连通无向图, ∃ V ′ ⊆ V \exists V'\subseteq V VV,去掉 V ′ V' V 及相关边后 G G G 不连通,则 V ′ V' V G G G 的点割。

稀疏图/稠密图(Sparse Graph / Dense Graph)

  • 稀疏图:对于图 G = ( V , E ) G=(V,E) G=(V,E),若 ∣ E ∣ ≪ ∣ V ∣ 2 |E| \ll |V|^2 EV2(这里 ≪ \ll 示意边数量远小于顶点数量平方的大概关系),则 G G G 为稀疏图,如: G = ( V , E ) G=(V,E) G=(V,E),当 ∣ E ∣ ≪ ∣ V ∣ 2 |E| \ll |V|^2 EV2 时, G G G 为稀疏图。

  • 稠密图:与稀疏图对应,若 ∣ E ∣ |E| E 接近 ∣ V ∣ 2 |V|^2 V2 量级,可写成: G = ( V , E ) G=(V,E) G=(V,E),当 ∣ E ∣ |E| E 接近 ∣ V ∣ 2 |V|^2 V2 时, G G G 为稠密图。

补图(Complement Graph)

​ 设 G = ( V , E ) G=(V,E) G=(V,E) 是无向简单图,其补图 G ‾ = ( V , E ‾ ) \overline{G}=(V,\overline{E}) G=(V,E),其中 E ‾ \overline{E} E 包含了所有不在 E E E 中但两端点在 V V V 中的边,可表示为: G = ( V , E ) G=(V,E) G=(V,E) 为无向简单图,其补图 G ‾ = ( V , E ‾ ) \overline{G}=(V,\overline{E}) G=(V,E) E ‾ = { ( u , v ) ∣ u , v ∈ V , ( u , v ) ∉ E } \overline{E}=\{(u,v)\mid u,v\in V,(u,v)\notin E\} E={(u,v)u,vV,(u,v)/E}

反图(Inverse Graph)

​ 对于有向图 G = ( V , E ) G=(V,E) G=(V,E),其反图 G − 1 = ( V , E − 1 ) G^{-1}=(V,E^{-1}) G1=(V,E1),这里 E − 1 E^{-1} E1 是把 E E E 中每条边的方向都反转所得到的边集,写成: G = ( V , E ) G=(V,E) G=(V,E) 为有向图,其反图 G − 1 = ( V , E − 1 ) G^{-1}=(V,E^{-1}) G1=(V,E1) E − 1 = { ( v , u ) ∣ ( u , v ) ∈ E } E^{-1}=\{(v,u)\mid (u,v)\in E\} E1={(v,u)(u,v)E}

特殊的图

完全图(Complete Graph)

  • 无向完全图:用 K n K_n Kn 表示 n n n 个顶点的无向完全图,其边数为 n ( n − 1 ) 2 \frac{n(n - 1)}{2} 2n(n1)。例如: K 5 K_5 K5 是有 5 5 5 个顶点的无向完全图,边数为 5 × ( 5 − 1 ) 2 = 10 \frac{5\times(5 - 1)}{2}=10 25×(51)=10
  • 有向完全图:用 D n D_n Dn 表示 n n n 个顶点的有向完全图,其边数为 n ( n − 1 ) n(n - 1) n(n1)
  • 树(Tree):树可描述为无向连通且无环的图,记为: T = ( V , E ) T=(V,E) T=(V,E) 为树,即 T T T 是无向连通且无环的图。
  • 二分图(Bipartite Graph):设顶点集 V V V 可分成两个互不相交的子集 V 1 V_1 V1 V 2 V_2 V2,使图中每条边的两个端点分别属于 V 1 V_1 V1 V 2 V_2 V2,可写成: G = ( V , E ) G=(V,E) G=(V,E) 为二分图, ∃ V 1 , V 2 ⊆ V \exists V_1,V_2\subseteq V V1,V2V V 1 ∩ V 2 = ∅ V_1\cap V_2=\varnothing V1V2=,且 ∀ e = ( u , v ) ∈ E \forall e=(u,v)\in E e=(u,v)E u ∈ V 1 u\in V_1 uV1 v ∈ V 2 v\in V_2 vV2 u ∈ V 2 u\in V_2 uV2 v ∈ V 1 v\in V_1 vV1

同构(Isomorphism)

​ 设 G = ( V , E ) G=(V,E) G=(V,E) G ′ = ( V ′ , E ′ ) G'=(V',E') G=(V,E) 是两个图,若存在双射函数 f : V → V ′ f: V \to V' f:VV,使得对于任意的 u , v ∈ V u,v \in V u,vV ( u , v ) ∈ E (u,v) \in E (u,v)E 当且仅当 ( f ( u ) , f ( v ) ) ∈ E ′ (f(u),f(v)) \in E' (f(u),f(v))E,则称 G G G G ′ G' G 是同构的,表示为: G = ( V , E ) G=(V,E) G=(V,E) G ′ = ( V ′ , E ′ ) G'=(V',E') G=(V,E),若 ∃ f : V → V ′ \exists f: V \to V' f:VV 双射,满足 ∀ u , v ∈ V \forall u,v\in V u,vV ( u , v ) ∈ E ⇔ ( f ( u ) , f ( v ) ) ∈ E ′ (u,v)\in E \Leftrightarrow (f(u),f(v))\in E' (u,v)E(f(u),f(v))E,则 G G G G ′ G' G 同构。

无向简单图的二元运算

并运算(Union):设 G 1 = ( V 1 , E 1 ) G_1=(V_1,E_1) G1=(V1,E1) G 2 = ( V 2 , E 2 ) G_2=(V_2,E_2) G2=(V2,E2) 是两个无向简单图,它们的并 G 1 ∪ G 2 = ( V 1 ∪ V 2 , E 1 ∪ E 2 ) G_1\cup G_2=(V_1\cup V_2, E_1\cup E_2) G1G2=(V1V2,E1E2),可写成: G 1 = ( V 1 , E 1 ) G_1=(V_1,E_1) G1=(V1,E1) G 2 = ( V 2 , E 2 ) G_2=(V_2,E_2) G2=(V2,E2),则 G 1 ∪ G 2 = ( V 1 ∪ V 2 , E 1 ∪ E 2 ) G_1\cup G_2=(V_1\cup V_2, E_1\cup E_2) G1G2=(V1V2,E1E2)。例如:已知 G 1 G_1 G1 G 2 G_2 G2 两个无向简单图,计算它们的并图 G 1 ∪ G 2 G_1\cup G_2 G1G2

交运算(Intersection) G 1 ∩ G 2 = ( V 1 ∩ V 2 , E 1 ∩ E 2 ) G_1\cap G_2=(V_1\cap V_2, E_1\cap E_2) G1G2=(V1V2,E1E2),表示为: G 1 = ( V 1 , E 1 ) G_1=(V_1,E_1) G1=(V1,E1) G 2 = ( V 2 , E 2 ) G_2=(V_2,E_2) G2=(V2,E2),则 G 1 ∩ G 2 = ( V 1 ∩ V 2 , E 1 ∩ E 2 ) G_1\cap G_2=(V_1\cap V_2, E_1\cap E_2) G1G2=(V1V2,E1E2)

差运算(Difference) G 1 − G 2 = ( V 1 , E 1 − E 2 ) G_1 - G_2=(V_1, E_1 - E_2) G1G2=(V1,E1E2),写成: G 1 = ( V 1 , E 1 ) G_1=(V_1,E_1) G1=(V1,E1) G 2 = ( V 2 , E 2 ) G_2=(V_2,E_2) G2=(V2,E2),则 G 1 − G 2 = ( V 1 , E 1 − E 2 ) G_1 - G_2=(V_1, E_1 - E_2) G1G2=(V1,E1E2)

特殊的点集/边集

支配集(Dominating Set)

​ 在无向图 G = ( V , E ) G=(V,E) G=(V,E) 中,顶点子集 D ⊆ V D\subseteq V DV 称为支配集,若对任意顶点 v ∈ V − D v\in V - D vVD,都存在顶点 u ∈ D u\in D uD 使得 u u u v v v 相邻,可表示为: G = ( V , E ) G=(V,E) G=(V,E) 无向图, ∃ D ⊆ V \exists D\subseteq V DV ∀ v ∈ V − D \forall v\in V - D vVD ∃ u ∈ D \exists u\in D uD u ∼ v u \sim v uv,则 D D D 为支配集。

边支配集(Edge Dominating Set)

​ 在无向图 G = ( V , E ) G=(V,E) G=(V,E) 中,边子集 F ⊆ E F\subseteq E FE 称为边支配集,若对任意边 e ∈ E − F e\in E - F eEF,都存在边 f ∈ F f\in F fF e e e 相邻(共享端点),写成: G = ( V , E ) G=(V,E) G=(V,E) 无向图, ∃ F ⊆ E \exists F\subseteq E FE ∀ e ∈ E − F \forall e\in E - F eEF ∃ f ∈ F \exists f\in F fF e e e f f f 共享端点,则 F F F 为边支配集。

独立集(Independent Set)

​ 在无向图 G = ( V , E ) G=(V,E) G=(V,E) 中,顶点子集 I ⊆ V I\subseteq V IV 称为独立集,若 I I I 中任意两个顶点都不相邻,即: G = ( V , E ) G=(V,E) G=(V,E) 无向图, ∃ I ⊆ V \exists I\subseteq V IV ∀ u , v ∈ I \forall u,v\in I u,vI u u u v v v 不相邻,则 I I I 为独立集。

匹配(Matching)

​ 在无向图 G = ( V , E ) G=(V,E) G=(V,E) 中,边子集 M ⊆ E M\subseteq E ME 称为匹配,若 M M M 中的边两两之间没有公共端点,可表示为: G = ( V , E ) G=(V,E) G=(V,E) 无向图, ∃ M ⊆ E \exists M\subseteq E ME ∀ e 1 , e 2 ∈ M \forall e_1,e_2\in M e1,e2M e 1 e_1 e1 e 2 e_2 e2 无公共端点,则 M M M 为匹配。

点覆盖(Vertex Cover)

​ 在无向图 G = ( V , E ) G=(V,E) G=(V,E) 中,顶点子集 C ⊆ V C\subseteq V CV 称为点覆盖,若图 G G G 中的每条边至少有一个端点在 C C C 中,写成: G = ( V , E ) G=(V,E) G=(V,E) 无向图, ∃ C ⊆ V \exists C\subseteq V CV ∀ e ∈ E \forall e\in E eE ∃ v ∈ C \exists v\in C vC v v v e e e 的端点,则 C C C 为点覆盖。

边覆盖(Edge Cover)

​ 在无向图 G = ( V , E ) G=(V,E) G=(V,E) 中,边子集 L ⊆ E L\subseteq E LE 称为边覆盖,若对于任意顶点 v ∈ V v\in V vV,都存在边 e ∈ L e\in L eL 使得 v v v e e e 的端点,可表示为: G = ( V , E ) G=(V,E) G=(V,E) 无向图, ∃ L ⊆ E \exists L\subseteq E LE ∀ v ∈ V \forall v\in V vV ∃ e ∈ L \exists e\in L eL v v v e e e 的端点,则 L L L 为边覆盖。

团(Clique)

​ 在无向图 G = ( V , E ) G=(V,E) G=(V,E) 中,顶点子集 K ⊆ V K\subseteq V KV 称为团,若 K K K 中任意两个顶点都相邻,即 K K K 所诱导出的子图是完全图,可表示为: G = ( V , E ) G=(V,E) G=(V,E) 无向图, ∃ K ⊆ V \exists K\subseteq V KV ∀ u , v ∈ K \forall u,v\in K u,vK u ∼ v u \sim v uv,则 K K K 为团。

图的矩阵表示(存储方式)

邻接矩阵(Adjacency Matrix)

对于一个无向图 G = ( V , E ) G=(V,E) G=(V,E) ,设顶点集 V = { v 1 , v 2 , ⋯   , v n } V = \{v_1, v_2, \cdots, v_n\} V={v1,v2,,vn},其邻接矩阵 A A A 是一个 n × n n\times n n×n 的矩阵,其中元素 a i j a_{ij} aij 定义为:若顶点 v i v_i vi v j v_j vj 相邻,则 a i j = 1 a_{ij} = 1 aij=1(对于无向简单图);若不相邻,则 a i j = 0 a_{ij} = 0 aij=0

用公式表示为: a i j = { 1 , v i ∼ v j 相邻 0 , v i ∼ v j 不相邻 a_{ij} = \begin{cases}1, & v_i \sim v_j\text{相邻} \\ 0, & v_i \sim v_j\text{不相邻}\end{cases} aij={1,0,vivj相邻vivj不相邻

例如,对于一个简单的三角形形状的无向图,其邻接矩阵为: ( 0 1 1 1 0 1 1 1 0 ) \begin{pmatrix}0 & 1 & 1 \\ 1 & 0 & 1 \\ 1 & 1 & 0\end{pmatrix} 011101110

对于有向图,若存在从顶点 v i v_i vi 指向 v j v_j vj 的边,则 a i j = 1 a_{ij} = 1 aij=1,否则 a i j = 0 a_{ij} = 0 aij=0。其邻接矩阵能反映出有向图中顶点之间的有向连接关系。

关联矩阵(Incidence Matrix)

设无向图 G = ( V , E ) G=(V,E) G=(V,E) ,顶点集 V = { v 1 , v 2 , ⋯   , v n } V = \{v_1, v_2, \cdots, v_n\} V={v1,v2,,vn},边集 E = { e 1 , e 2 , ⋯   , e m } E = \{e_1, e_2, \cdots, e_m\} E={e1,e2,,em},其关联矩阵 M M M 是一个 n × m n\times m n×m 的矩阵,元素 m i j m_{ij} mij 定义如下:若顶点 v i v_i vi 与边 e j e_j ej 关联(即 v i v_i vi e j e_j ej 的一个端点),则 m i j = 1 m_{ij} = 1 mij=1;若不关联,则 m i j = 0 m_{ij} = 0 mij=0

用公式表示为: m i j = { 1 , 如果 v i 关联 e j 0 , 如果 v i 不关联 e j m_{ij} = \begin{cases}1, & \text{如果} v_i \text{关联} e_j \\ 0, & \text{如果} v_i \text{不关联} e_j\end{cases} mij={1,0,如果vi关联ej如果vi不关联ej

例如,对于一个简单的有四条边、三个顶点的无向图,其关联矩阵可能为: ( 1 1 0 0 1 0 1 1 0 1 1 0 ) \begin{pmatrix}1 & 1 & 0 & 0 \\ 1 & 0 & 1 & 1 \\ 0 & 1 & 1 & 0\end{pmatrix} 110101011010 。 有向图的关联矩阵定义稍有不同,对于有向边 e j e_j ej ,若顶点 v i v_i vi 是边 e j e_j ej 的起点,则 m i j = 1 m_{ij} = 1 mij=1;若 v i v_i vi 是边 e j e_j ej 的终点,则 m i j = − 1 m_{ij} = -1 mij=1;若 v i v_i vi e j e_j ej 不关联,则 m i j = 0 m_{ij} = 0 mij=0

2、图的存储

n为图的顶点数,m为图的边数, d + ( u ) d^+(u) d+(u)为点u的出度, d − ( u ) d^-(u) d(u)为点u的入度

2.1、直接存边

实现:

使用多个数组来存储变得起点终点和权值。

复杂度:

查询是否存在某条边: O ( m ) O(m) O(m)

遍历一个点的所有出边: O ( m ) O(m) O(m)

遍历整张图: O ( n m ) O(nm) O(nm)

空间复杂度: O ( m ) O(m) O(m)

注:在Kruskal算法中,需要把边按权值排序,需要直接存储边。

2.2、邻接矩阵

实现:

使用二维数组 a d j [ u ] [ v ] adj[u][v] adj[u][v] 来存储, a d j [ u ] [ v ] adj[u][v] adj[u][v]的值表示 u u u v v v 是否有边。

用公式表示为: a d j [ u ] [ v ] = { 1 , 存在 u 到 v 的边 0 , 不存在 u 到 v 的边 adj[u][v]= \left\{\begin{matrix} 1 &,存在u到v的边\\ 0 &,不存在u到v的边 \end{matrix}\right. adj[u][v]={10,存在uv的边,不存在uv的边

代码

复杂度:

查询是否存在某条边: O ( 1 ) O(1) O(1)

遍历一个点的所有出边: O ( n ) O(n) O(n)

遍历整张图: O ( n 2 ) O(n^2) O(n2)

空间复杂度: O ( n 2 ) O(n^2) O(n2)

邻接矩阵只适用于没有重边的图

由于邻接矩阵在稀疏图上效率很低(尤其是在点数较多的图上,空间无法承受),所以一般只会在稠密图上使用邻接矩阵。

2.3、邻接表

2.4、链式前向星


原文地址:https://blog.csdn.net/Amazing_snack/article/details/144224844

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!