mirror of
https://github.com/krahets/hello-algo.git
synced 2026-07-25 20:46:08 +00:00
build
This commit is contained in:
@@ -16,7 +16,7 @@ $$
|
||||
|
||||

|
||||
|
||||
<p align="center"> Fig. 链表、树、图之间的关系 </p>
|
||||
<p align="center"> 图:链表、树、图之间的关系 </p>
|
||||
|
||||
那么,图与其他数据结构的关系是什么?如果我们把「顶点」看作节点,把「边」看作连接各个节点的指针,则可将「图」看作是一种从「链表」拓展而来的数据结构。**相较于线性关系(链表)和分治关系(树),网络关系(图)的自由度更高,从而更为复杂**。
|
||||
|
||||
@@ -29,7 +29,7 @@ $$
|
||||
|
||||

|
||||
|
||||
<p align="center"> Fig. 有向图与无向图 </p>
|
||||
<p align="center"> 图:有向图与无向图 </p>
|
||||
|
||||
根据所有顶点是否连通,可分为「连通图 Connected Graph」和「非连通图 Disconnected Graph」。
|
||||
|
||||
@@ -38,13 +38,13 @@ $$
|
||||
|
||||

|
||||
|
||||
<p align="center"> Fig. 连通图与非连通图 </p>
|
||||
<p align="center"> 图:连通图与非连通图 </p>
|
||||
|
||||
我们还可以为边添加“权重”变量,从而得到「有权图 Weighted Graph」。例如,在王者荣耀等手游中,系统会根据共同游戏时间来计算玩家之间的“亲密度”,这种亲密度网络就可以用有权图来表示。
|
||||
|
||||

|
||||
|
||||
<p align="center"> Fig. 有权图与无权图 </p>
|
||||
<p align="center"> 图:有权图与无权图 </p>
|
||||
|
||||
## 9.1.2. 图常用术语
|
||||
|
||||
@@ -64,7 +64,7 @@ $$
|
||||
|
||||

|
||||
|
||||
<p align="center"> Fig. 图的邻接矩阵表示 </p>
|
||||
<p align="center"> 图:图的邻接矩阵表示 </p>
|
||||
|
||||
邻接矩阵具有以下特性:
|
||||
|
||||
@@ -80,7 +80,7 @@ $$
|
||||
|
||||

|
||||
|
||||
<p align="center"> Fig. 图的邻接表表示 </p>
|
||||
<p align="center"> 图:图的邻接表表示 </p>
|
||||
|
||||
邻接表仅存储实际存在的边,而边的总数通常远小于 $n^2$ ,因此它更加节省空间。然而,在邻接表中需要通过遍历链表来查找边,因此其时间效率不如邻接矩阵。
|
||||
|
||||
|
||||
@@ -30,6 +30,8 @@ comments: true
|
||||
=== "删除顶点"
|
||||

|
||||
|
||||
<p align="center"> 图:邻接矩阵的初始化、增删边、增删顶点 </p>
|
||||
|
||||
以下是基于邻接矩阵表示图的实现代码。
|
||||
|
||||
=== "Java"
|
||||
@@ -1147,6 +1149,8 @@ comments: true
|
||||
=== "删除顶点"
|
||||

|
||||
|
||||
<p align="center"> 图:邻接表的初始化、增删边、增删顶点 </p>
|
||||
|
||||
以下是基于邻接表实现图的代码示例。细心的同学可能注意到,**我们在邻接表中使用 `Vertex` 节点类来表示顶点**,这样做的原因有:
|
||||
|
||||
- 如果我们选择通过顶点值来区分不同顶点,那么值重复的顶点将无法被区分。
|
||||
@@ -1533,7 +1537,7 @@ comments: true
|
||||
// 在邻接表中删除顶点 vet 对应的链表
|
||||
this.adjList.delete(vet);
|
||||
// 遍历其他顶点的链表,删除所有包含 vet 的边
|
||||
for (let set of this.adjList.values()) {
|
||||
for (const set of this.adjList.values()) {
|
||||
const index = set.indexOf(vet);
|
||||
if (index > -1) {
|
||||
set.splice(index, 1);
|
||||
@@ -1622,7 +1626,7 @@ comments: true
|
||||
// 在邻接表中删除顶点 vet 对应的链表
|
||||
this.adjList.delete(vet);
|
||||
// 遍历其他顶点的链表,删除所有包含 vet 的边
|
||||
for (let set of this.adjList.values()) {
|
||||
for (const set of this.adjList.values()) {
|
||||
const index: number = set.indexOf(vet);
|
||||
if (index > -1) {
|
||||
set.splice(index, 1);
|
||||
|
||||
@@ -18,7 +18,7 @@ comments: true
|
||||
|
||||

|
||||
|
||||
<p align="center"> Fig. 图的广度优先遍历 </p>
|
||||
<p align="center"> 图:图的广度优先遍历 </p>
|
||||
|
||||
### 算法实现
|
||||
|
||||
@@ -427,6 +427,8 @@ BFS 通常借助「队列」来实现。队列具有“先入先出”的性质
|
||||
=== "<11>"
|
||||

|
||||
|
||||
<p align="center"> 图:图的广度优先遍历步骤 </p>
|
||||
|
||||
!!! question "广度优先遍历的序列是否唯一?"
|
||||
|
||||
不唯一。广度优先遍历只要求按“由近及远”的顺序遍历,**而多个相同距离的顶点的遍历顺序是允许被任意打乱的**。以上图为例,顶点 $1$ , $3$ 的访问顺序可以交换、顶点 $2$ , $4$ , $6$ 的访问顺序也可以任意交换。
|
||||
@@ -443,7 +445,7 @@ BFS 通常借助「队列」来实现。队列具有“先入先出”的性质
|
||||
|
||||

|
||||
|
||||
<p align="center"> Fig. 图的深度优先遍历 </p>
|
||||
<p align="center"> 图:图的深度优先遍历 </p>
|
||||
|
||||
### 算法实现
|
||||
|
||||
@@ -835,6 +837,8 @@ BFS 通常借助「队列」来实现。队列具有“先入先出”的性质
|
||||
=== "<11>"
|
||||

|
||||
|
||||
<p align="center"> 图:图的深度优先遍历步骤 </p>
|
||||
|
||||
!!! question "深度优先遍历的序列是否唯一?"
|
||||
|
||||
与广度优先遍历类似,深度优先遍历序列的顺序也不是唯一的。给定某顶点,先往哪个方向探索都可以,即邻接顶点的顺序可以任意打乱,都是深度优先遍历。
|
||||
|
||||
Reference in New Issue
Block a user