图的宽度优先搜索树与最短路径树
字数 2400 2025-11-05 23:46:51

图的宽度优先搜索树与最短路径树

好的,我们开始学习“图的宽度优先搜索树与最短路径树”。这是一个将图的遍历算法与其一个重要应用紧密结合的词条。

步骤1:回顾基础——宽度优先搜索(BFS)算法

在深入探讨“树”之前,我们必须清晰地理解宽度优先搜索(BFS) 的过程。BFS是一种用于遍历或搜索图或树的算法。它的核心思想是“由近及远”,一层一层地探索图中的顶点。

  • 算法过程:从一个源顶点 s 开始。

    1. 首先访问 s
    2. 然后访问所有与 s 直接相邻(距离为1)的、尚未被访问的顶点。
    3. 接着,访问所有与第一层顶点相邻(距离为2)的、尚未被访问的顶点。
    4. 依此类推,直到图中所有从 s 可达的顶点都被访问到。
  • 关键数据结构:BFS使用一个队列(Queue) 来管理待访问的顶点。队列“先进先出”的特性保证了顶点是按照它们被发现的顺序(即距离 s 从近到远的顺序)来被访问的。

  • 辅助记录:在算法执行过程中,我们通常为每个顶点 v 维护两个信息:

    • visited[v]:标记顶点 v 是否已被访问。
    • parent[v](或 predecessor[v]):记录是哪个顶点在BFS过程中首先发现v。对于源顶点 s,我们设 parent[s] = NULL

步骤2:从遍历过程到生成树——BFS树的定义

BFS不仅仅是一个遍历顺序,它通过在遍历过程中记录的“父子关系”,隐式地构建了一棵树。

  • BFS树的形成:在BFS算法中,当我们从顶点 u 探索到其未被访问的邻居 v 时,我们设置 parent[v] = u。这个 u -> v 的关系,在图的语境下是一条边,在树的语境下就是一条“父子边”。
  • 正式定义:对于一个给定的图 G 和一个源顶点 sBFS树 是一个以 s 为根的子图。它包含了从 s 出发可达的所有顶点,并且连接这些顶点的边正是由BFS过程中记录的 parent 关系所定义的边的集合。
  • 重要性质:在BFS树中,从根节点 s 到任意可达节点 v唯一路径,就是图中从 sv一条最短路径(按经过的边数计算,即跳数)。这是因为BFS是按照距离源点的层次来遍历的,保证了当它首次访问一个顶点时,所经过的路径一定是最短的。

步骤3:从BFS树到最短路径树(SPT)——概念的泛化

BFS树解决的是无权图(或视所有边权为1的图)的最短路径问题。最短路径树(Shortest Path Tree, SPT) 是这个概念在带权图上的推广。

  • 边权:在现实世界的图中,边通常具有权重(如距离、时间、成本等)。最短路径的目标就不再是经过最少的边数,而是找到一条路径,使得路径上所有边的权重之和最小。
  • SPT的定义:给定一个带非负权重的连通图 G 和一个源顶点 s最短路径树是一棵以 s 为根的生成树(包含图的所有顶点),使得对于树中任意顶点 v,从 sv唯一树路径,就是原图中从 sv一条权重和最小的最短路径
  • 关键点:一棵SPT必须同时满足两个条件:
    1. 它是一棵生成树(或至少是包含s的连通分量的生成树)。
    2. 它完美地编码了从源点 s所有其他顶点的最短路径信息。

步骤4:构建最短路径树——Dijkstra算法

对于带非负权重的图,最经典的SPT构建算法是Dijkstra算法。你可以将Dijkstra算法理解为BFS算法在带权图上的泛化。

  • 算法思想类比
    • BFS使用队列,按照“距离s的跳数”递增的顺序处理顶点。
    • Dijkstra算法使用优先队列(通常是最小堆),按照“当前已知的从s出发的路径总权重(称为‘距离’)”递增的顺序处理顶点。
  • 算法过程简述
    1. 初始化:设置源点 s 的距离为0,其他所有顶点的距离为无穷大。所有顶点的 parent 为未定义。将 s 加入优先队列。
    2. 当优先队列非空时,取出当前距离 s 最近的顶点 u
    3. 遍历 u 的所有邻居 v。计算一条新的潜在路径:s -> ... -> u -> v,其总权重为 dist[u] + weight(u, v)
    4. 如果这个新权重小于 v 当前记录的距离 dist[v],则更新 dist[v] 为这个更小的值,并设置 parent[v] = u。同时将 v(或其更新后的距离)加入优先队列。
    5. 算法结束时,parent[] 数组就定义了一棵最短路径树。

步骤5:总结与比较

让我们最后清晰地对比一下这两个紧密相关的概念:

特征 宽度优先搜索树(BFS Tree) 最短路径树(Shortest Path Tree, SPT)
适用图类型 无权图(或等价于边权为1的图) 带权图(要求非负权,如Dijkstra算法)
核心目标 找到从源点出发,经过边数最少的路径。 找到从源点出发,路径权重之和最小的路径。
构建算法 宽度优先搜索(BFS) Dijkstra算法(对于非负权)、Bellman-Ford算法(可处理负权但无负权环)
数据结构 队列(Queue) 优先队列(Priority Queue)
关系 BFS树是SPT在无权图情况下的一个特例。 SPT是BFS树概念在带权图上的泛化。

理解这两个概念的关键在于认识到,BFS树是最短路径问题在最简单模型(无权图)下的完美解决方案,而最短路径树则是将这一解决方案扩展到了更复杂、更一般的模型(带权图)中。

图的宽度优先搜索树与最短路径树 好的,我们开始学习“图的宽度优先搜索树与最短路径树”。这是一个将图的遍历算法与其一个重要应用紧密结合的词条。 步骤1:回顾基础——宽度优先搜索(BFS)算法 在深入探讨“树”之前,我们必须清晰地理解 宽度优先搜索(BFS) 的过程。BFS是一种用于遍历或搜索图或树的算法。它的核心思想是“由近及远”,一层一层地探索图中的顶点。 算法过程 :从一个源顶点 s 开始。 首先访问 s 。 然后访问所有与 s 直接相邻(距离为1)的、尚未被访问的顶点。 接着,访问所有与第一层顶点相邻(距离为2)的、尚未被访问的顶点。 依此类推,直到图中所有从 s 可达的顶点都被访问到。 关键数据结构 :BFS使用一个 队列(Queue) 来管理待访问的顶点。队列“先进先出”的特性保证了顶点是按照它们被发现的顺序(即距离 s 从近到远的顺序)来被访问的。 辅助记录 :在算法执行过程中,我们通常为每个顶点 v 维护两个信息: visited[v] :标记顶点 v 是否已被访问。 parent[v] (或 predecessor[v] ):记录是 哪个顶点 在BFS过程中 首先发现 了 v 。对于源顶点 s ,我们设 parent[s] = NULL 。 步骤2:从遍历过程到生成树——BFS树的定义 BFS不仅仅是一个遍历顺序,它通过在遍历过程中记录的“父子关系”,隐式地构建了一棵树。 BFS树的形成 :在BFS算法中,当我们从顶点 u 探索到其未被访问的邻居 v 时,我们设置 parent[v] = u 。这个 u -> v 的关系,在图的语境下是一条边,在树的语境下就是一条“父子边”。 正式定义 :对于一个给定的图 G 和一个源顶点 s , BFS树 是一个以 s 为根的子图。它包含了从 s 出发可达的所有顶点,并且连接这些顶点的边正是由BFS过程中记录的 parent 关系所定义的边的集合。 重要性质 :在BFS树中,从根节点 s 到任意可达节点 v 的 唯一路径 ,就是图中从 s 到 v 的 一条最短路径 (按经过的边数计算,即跳数)。这是因为BFS是按照距离源点的层次来遍历的,保证了当它首次访问一个顶点时,所经过的路径一定是最短的。 步骤3:从BFS树到最短路径树(SPT)——概念的泛化 BFS树解决的是 无权图 (或视所有边权为1的图)的最短路径问题。 最短路径树(Shortest Path Tree, SPT) 是这个概念在 带权图 上的推广。 边权 :在现实世界的图中,边通常具有权重(如距离、时间、成本等)。最短路径的目标就不再是经过最少的边数,而是找到一条路径,使得路径上所有边的权重之和最小。 SPT的定义 :给定一个带非负权重的连通图 G 和一个源顶点 s , 最短路径树 是一棵以 s 为根的生成树(包含图的所有顶点),使得对于树中任意顶点 v ,从 s 到 v 的 唯一树路径 ,就是原图中从 s 到 v 的 一条权重和最小的最短路径 。 关键点 :一棵SPT必须同时满足两个条件: 它是一棵生成树(或至少是包含s的连通分量的生成树)。 它完美地编码了从源点 s 到 所有其他顶点 的最短路径信息。 步骤4:构建最短路径树——Dijkstra算法 对于带非负权重的图,最经典的SPT构建算法是 Dijkstra算法 。你可以将Dijkstra算法理解为BFS算法在带权图上的泛化。 算法思想类比 : BFS使用 队列 ,按照“距离s的跳数”递增的顺序处理顶点。 Dijkstra算法使用 优先队列(通常是最小堆) ,按照“当前已知的从s出发的路径总权重(称为‘距离’)”递增的顺序处理顶点。 算法过程简述 : 初始化:设置源点 s 的距离为0,其他所有顶点的距离为无穷大。所有顶点的 parent 为未定义。将 s 加入优先队列。 当优先队列非空时,取出当前距离 s 最近的顶点 u 。 遍历 u 的所有邻居 v 。计算一条新的潜在路径: s -> ... -> u -> v ,其总权重为 dist[u] + weight(u, v) 。 如果这个新权重小于 v 当前记录的距离 dist[v] ,则更新 dist[v] 为这个更小的值,并设置 parent[v] = u 。同时将 v (或其更新后的距离)加入优先队列。 算法结束时, parent[] 数组就定义了一棵最短路径树。 步骤5:总结与比较 让我们最后清晰地对比一下这两个紧密相关的概念: | 特征 | 宽度优先搜索树(BFS Tree) | 最短路径树(Shortest Path Tree, SPT) | | :--- | :--- | :--- | | 适用图类型 | 无权图 (或等价于边权为1的图) | 带权图 (要求非负权,如Dijkstra算法) | | 核心目标 | 找到从源点出发,经过边数最少的路径。 | 找到从源点出发,路径权重之和最小的路径。 | | 构建算法 | 宽度优先搜索(BFS) | Dijkstra算法 (对于非负权)、Bellman-Ford算法(可处理负权但无负权环) | | 数据结构 | 队列(Queue) | 优先队列(Priority Queue) | | 关系 | BFS树是SPT在无权图情况下的一个特例。 | SPT是BFS树概念在带权图上的泛化。 | 理解这两个概念的关键在于认识到,BFS树是最短路径问题在最简单模型(无权图)下的完美解决方案,而最短路径树则是将这一解决方案扩展到了更复杂、更一般的模型(带权图)中。