欢迎光临
我们一直在努力

【408数据结构】核心考点:图(Graph)精炼笔记与算法直觉


💡 博主前言:本文整理自个人的 408 计算机考研复习笔记。本书写特点是拒绝死记硬背,用最直观的大白话提炼算法的核心直觉。笔记中针对高频考点进行了梳理,并对邻接矩阵幂次原理、Prim 与 Dijkstra 算法的“集合思想”进行了深度扩展与全流程图解。希望能帮到一起备考的伙伴们!


文章目录

    • 📌 一、 图的基本概念与核心性质
      • 1. 基础定义与边数关系
      • 2. 路径与环
      • 3. 子图与连通性
    • 💾 二、 图的存储结构与底层原理
      • 1. 邻接矩阵(Adjacency Matrix)
        • 🔍 【高频探究】邻接矩阵幂次

          A

          k

          [

          i

          ]

          [

          j

          ]

          A^k[i][j]

          Ak[i][j] 的物理意义与原理

      • 2. 邻接表(Adjacency List)
      • 3. 其他高效存储结构(408常考选填题)
    • 🎯 三、 图的遍历算法直觉(大白话总结)
      • 1. DFS(深度优先搜索)
      • 2. BFS(广度优先搜索)
    • 🛠️ 四、 图的核心算法:基于“集合思想”的深度对决
      • 📝 【红字突破】Dijkstra 与 Prim “集合思想”的同台对比例题
        • 1. 实例场景设定
        • 2. 第一步(Prim 与 Dijkstra 决策相同)
        • 3. 第二步(分歧产生的命运转折点!)
          • 🌳 方案 A:Prim 算法(目标:连通全图,怎么省钱怎么来)
          • 🛣️ 方案 B:Dijkstra 算法(目标:每个人回老家

            V

            0

            V_0

            V0​ 的车费最便宜)

      • 💡 核心总结

📌 一、 图的基本概念与核心性质

1. 基础定义与边数关系

  • 弧头与弧尾(有向边):有向边表示为

    ⟨

    v

    1

    ,

    v

    2

    ⟩

    \\langle v_1, v_2 \\rangle

    ⟨v1​,v2​⟩,有向边的终点叫弧头(Arrowhead),起点叫弧尾(Arrowtail)。

  • 示例:对于有向边

    v

    1

    →

    v

    2

    v_1 \\to v_2

    v1​→v2​,

    v

    2

    v_2

    v2​ 是弧头,

    v

    1

    v_1

    v1​ 是弧尾。

  • 顶点的度、入度与出度:

  • 无向图:顶点的度数之和等于边数的 2 倍,即

    ∑

    D

    (

    v

    )

    =

    2

    e

    \\sum D(v) = 2e

    ∑D(v)=2e。

  • 有向图:

  • 总入度 = 总出度 = 边数

    e

    e

    e,即

    ∑

    I

    D

    (

    v

    )

    =

    ∑

    O

    D

    (

    v

    )

    =

    e

    \\sum ID(v) = \\sum OD(v) = e

    ∑ID(v)=∑OD(v)=e。

  • 有向图中顶点的度数之和为入度与出度之和,即

    ∑

    D

    (

    v

    )

    =

    2

    ×

    入度

    =

    2

    ×

    出度

    =

    2

    e

    \\sum D(v) = 2 \\times \\text{入度} = 2 \\times \\text{出度} = 2e

    ∑D(v)=2×入度=2×出度=2e。

  • 完全图的边数上限公式:

  • 无向完全图:

    n

    n

    n 个顶点,任意两点间都有一条边

    ⇒

    \\Rightarrow

    ⇒ 边数

    e

    =

    n

    (

    n

    −

    1

    )

    2

    e = \\frac{n(n-1)}{2}

    e=2n(n−1)​。

  • 有向完全图:

    n

    n

    n 个顶点,任意两点间都有方向相反的两条有向边

    ⇒

    \\Rightarrow

    ⇒ 边数

    e

    =

    n

    (

    n

    −

    1

    )

    e = n(n-1)

    e=n(n−1)。

2. 路径与环

  • 路径:顶点序列

    v

    1

    ,

    v

    2

    ,

    v

    3

    …

    v_1, v_2, v_3 \\dots

    v1​,v2​,v3​… 构成的序列。若序列长度为 2,则包含 2 条边。

  • 回路(环):起点和终点是同一个顶点的路径。

3. 子图与连通性

  • 子图:顶点集和边集分别是父图的顶点集和边集的子集的图。(形象记忆:树苗是整棵大树的子图)。

  • 连通图(无向图):图中任意两个顶点之间都是连通的(即存在路径)。

  • 极大连通子图(连通分量):无向图中的非连通图,其极大的连通子部分。若任意添加一个顶点都会导致图变成非连通,则该子图为极大连通子图。

  • 极小连通子图(生成树):包含图中全部

    n

    n

    n 个顶点和

    n

    −

    1

    n-1

    n−1 条边的极小连通子图。

  • 🔥 核心直觉:若少一条边,则图不再连通;若多一条边,则图中必产生环。

  • 生成森林:由多个连通分量的生成树组成的非连通图。

  • 强连通图(有向图):有向图中任意两个顶点都存在双向路径(路径中可以包含中转顶点)。

  • 强连通分量:有向图中的极大强连通子图。


💾 二、 图的存储结构与底层原理

1. 邻接矩阵(Adjacency Matrix)

  • 存储方式:

  • 顶点数组:v[n](Vertex 顶点集)

  • 边数组:e[n][n](Edges 边集,二维数组)

  • 特点:适用于稠密图,空间利用率高。

  • 对称性:无向图的邻接矩阵都是对称矩阵,满足

    A

    =

    A

    T

    A = A^T

    A=AT,在实际工程中可以采用压缩存储(只存上三角或下三角)来节省空间。

🔍 【高频探究】邻接矩阵幂次

A

k

[

i

]

[

j

]

A^k[i][j]

Ak[i][j] 的物理意义与原理

❓ 思考红字:若邻接矩阵为

A

A

A,那么

e

d

g

e

s

k

[

i

]

[

j

]

edges^k[i][j]

edgesk[i][j] 表示从顶点

i

i

i 到顶点

j

j

j 之间长度为

k

k

k 的路径条数。它的底层数学原理是什么?

原理剖析:我们以

k

=

2

k=2

k=2 时的矩阵乘法公式展开:

A

2

[

i

]

[

j

]

=

∑

m

=

1

n

A

[

i

]

[

m

]

×

A

[

m

]

[

j

]

A^2[i][j] = \\sum_{m=1}^{n} A[i][m] \\times A[m][j]

A2[i][j]=m=1∑n​A[i][m]×A[m][j]

  • A

    [

    i

    ]

    [

    m

    ]

    =

    1

    A[i][m] = 1

    A[i][m]=1 表示存在边

    i

    →

    m

    i \\to m

    i→m;

  • A

    [

    m

    ]

    [

    j

    ]

    =

    1

    A[m][j] = 1

    A[m][j]=1 表示存在边

    m

    →

    j

    m \\to j

    m→j;

  • 只有当

    A

    [

    i

    ]

    [

    m

    ]

    ×

    A

    [

    m

    ]

    [

    j

    ]

    =

    1

    A[i][m] \\times A[m][j] = 1

    A[i][m]×A[m][j]=1 时,才说明存在一条通过中转点

    m

    m

    m 的路径

    i

    →

    m

    →

    j

    i \\to m \\to j

    i→m→j,其长度恰好为 2。

  • 通过

    ∑

    \\sum

    ∑ 对所有可能的中转点

    m

    m

    m 进行求和,得到的便是从

    i

    i

    i 到

    j

    j

    j 长度为 2 的路径总条数。以此类推,通过数学归纳法可证明

    A

    k

    [

    i

    ]

    [

    j

    ]

    A^k[i][j]

    Ak[i][j] 即为长度为

    k

    k

    k 的路径条数。


2. 邻接表(Adjacency List)

  • 空间复杂度:

  • 有向图:

    O

    (

    n

    +

    e

    )

    O(n+e)

    O(n+e)

  • 无向图:

    O

    (

    n

    +

    2

    e

    )

    O(n+2e)

    O(n+2e) (因为每条无向边在表中被记录了两次)

  • 🔥 出度/入度查询方法总结:

  • 顶点的出度极其容易获取,就是该顶点挂载的单链表中边结点的个数。

  • 顶点的入度则较为麻烦,需要遍历整个邻接表的所有链表才能统计出来。

3. 其他高效存储结构(408常考选填题)

  • 十字链表:用于优化有向图,能同时在常数或极短时间内获取出度和入度。
  • 邻接多重表:用于优化无向图,方便对边进行标记、删除等操作。

🎯 三、 图的遍历算法直觉(大白话总结)

对于图的深度优先(DFS)与广度优先(BFS)遍历,可以用两句极简的“算法直觉”来概括本质:

1. DFS(深度优先搜索)

  • 🔥 方法总结:“只要不成环,一直找邻居

    ⟶

    \\longrightarrow

    ⟶”

  • 算法直觉:这是一种“一条路走到黑”的贪心回溯思想。利用了栈(Stack)或递归的特性,只要当前顶点的邻居节点没有被访问过(不成环),就立刻深入访问邻居的邻居,直到撞到南墙再回溯。

2. BFS(广度优先搜索)

  • 🔥 方法总结:“逐层遍历 🎯”
  • 算法直觉:以初始起点为核心,像水波纹一样一层一层向外扩散。利用了队列(Queue)的特性,先访问当前节点的所有直接邻居(第一层),再依次访问邻居的邻居(第二层)。

🛠️ 四、 图的核心算法:基于“集合思想”的深度对决

在考研中,Prim算法、Kruskal算法与Dijkstra算法是手算模拟和算法理解的重中之重。下面先给出精炼总结,随后展开详细的例题对比。

  • 🔥 Prim(普里姆)算法:从初始顶点出发,逐个寻找离“这一集合”(集合初始只有起点)最近的点,且把这一点合并进集合,直到所有点都归并到集合。

  • 特质:加点法,时间复杂度与边数无关,适合稠密图。

  • 🔥 Kruskal(克鲁斯卡尔)算法:从最短边搭起,每一步连接当下最短的边(不允许成环),直到所有点都被连通。

  • 特质:加边法,通常采用并查集判环,适合稀疏图。

  • 🔥 Dijkstra(迪杰斯特拉)算法:与 Prim 一样,基于“集合”的思想。

  • 特质:单源最短路径算法。


📝 【红字突破】Dijkstra 与 Prim “集合思想”的同台对比例题

虽然 Prim 和 Dijkstra 都在执行“将红点(未加入集合)变为蓝点(已加入集合)”的操作,且都用到了贪心策略,但它们的更新代价(Distance)的逻辑有着本质的区别。

1. 实例场景设定

假设图中有三个顶点:

V

0

V_0

V0​(源点/起点)、

V

1

V_1

V1​、

V

2

V_2

V2​。 各边权重如下:

  • V

    0

    →

    V

    1

    V_0 \\to V_1

    V0​→V1​ = 2

  • V

    0

    →

    V

    2

    V_0 \\to V_2

    V0​→V2​ = 10

  • V

    1

    →

    V

    2

    V_1 \\to V_2

    V1​→V2​ = 3

我们将已选入的顶点划入集合

S

S

S,未选入的划入集合

V

−

S

V-S

V−S。初始状态下,

S

=

{

V

0

}

S = \\{V_0\\}

S={V0​}。

2. 第一步(Prim 与 Dijkstra 决策相同)
  • 此时未加入集合的点中,离

    V

    0

    V_0

    V0​ 最近的是

    V

    1

    V_1

    V1​(距离为 2)。

  • 将

    V

    1

    V_1

    V1​ 收入集合,此时已选集合

    S

    =

    {

    V

    0

    ,

    V

    1

    }

    S = \\{V_0, V_1\\}

    S={V0​,V1​}。

3. 第二步(分歧产生的命运转折点!)

现在我们需要决定如何将最后一个点

V

2

V_2

V2​ 纳入麾下。这时候两个算法在“计算距离”时展现出了完全不同的脑回路:

🌳 方案 A:Prim 算法(目标:连通全图,怎么省钱怎么来)
  • 计算逻辑:

    V

    2

    V_2

    V2​ 距离整个已选集合

    S

    {

    V

    0

    ,

    V

    1

    }

    S \\{V_0, V_1\\}

    S{V0​,V1​} 这个整体的最短单条边是谁?

  • 看

    V

    0

    →

    V

    2

    V_0 \\to V_2

    V0​→V2​ 边权是 10;

  • 看

    V

    1

    →

    V

    2

    V_1 \\to V_2

    V1​→V2​ 边权是 3。

  • 做出决策:通过

    V

    1

    V_1

    V1​ 连过去明显更省边权!所以 Prim 认为

    V

    2

    V_2

    V2​ 当前的候选距离是 3。

  • 最终结果:选择边

    (

    V

    1

    ,

    V

    2

    )

    (V_1, V_2)

    (V1​,V2​),最小生成树(MST)的总权重 =

    2

    +

    3

    =

    5

    2 + 3 = 5

    2+3=5。

🛣️ 方案 B:Dijkstra 算法(目标:每个人回老家

V

0

V_0

V0​ 的车费最便宜)

  • 计算逻辑:

    V

    2

    V_2

    V2​ 跨过集合后,回到“源点

    V

    0

    V_0

    V0​”的总累加路径长度是多少?

  • 直达路线

    V

    0

    →

    V

    2

    V_0 \\to V_2

    V0​→V2​:总长 10;

  • 中转路线

    V

    0

    →

    V

    1

    →

    V

    2

    V_0 \\to V_1 \\to V_2

    V0​→V1​→V2​:总长 =

    (

    V

    0

    →

    V

    1

    )

    +

    (

    V

    1

    →

    V

    2

    )

    =

    2

    +

    3

    =

    5

    (V_0 \\to V_1) + (V_1 \\to V_2) = 2 + 3 = 5

    (V0​→V1​)+(V1​→V2​)=2+3=5。

  • 做出决策:走中转路线总里程更短!Dijkstra 执行松弛操作(Relaxation):

    D

    [

    V

    2

    ]

    =

    min

    ⁡

    (

    10

    ,

    2

    +

    3

    )

    =

    5

    D[V_2] = \\min(10, 2+3) = 5

    D[V2​]=min(10,2+3)=5。Dijkstra 认为

    V

    2

    V_2

    V2​ 的最短路径值是 5。

  • 最终结果:求得

    V

    0

    V_0

    V0​ 到

    V

    2

    V_2

    V2​ 的最短路径长度为 5。


💡 核心总结

  • Prim 算法:每次向外探摸时,只关心红点到已选集合边界的单条最省边长(局部最优连通)。
  • Dijkstra 算法:每次向外探摸时,关心的是红点越过边界后,一路走回源点的总累加里程(全局最优路径)。

通过这种大白话的模型构建,无论是面对 408 考研中的选择题模拟,还是大题的手算,都能做到数感清晰,准确率百分之百!

赞(0)
未经允许不得转载:171主机测评 » 【408数据结构】核心考点:图(Graph)精炼笔记与算法直觉
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址