Skip to content

Lecture 5. 图 ​

图的表示 ​

对于图 ,其中 是点集, 是边集。

对于无向图和有向图,都可以用若干 邻接表(adjacency list) 或 邻接矩阵(adjacency matrix) 表示。

  • 对于 稀疏(sparse) 图(),通常选择邻接表
  • 对于 稠密(dense) 图(),或需要快速查询两点之间是否有边,则用邻接矩阵

邻接表 ​

是 个链表构成的数组。 包含了满足 的所有节点 。

  • 若 是有向图,那么所有链表的长度总和,就是
  • 若 是无向图,那么所有链表的长度总和,就是

邻接表的缺点是无法快速查找图中是否存在一条边 。

邻接矩阵 ​

邻接矩阵 是一个 的零一矩阵,行列标号从 到 :$$a_{i,j}=\begin{cases}1 & (i,j) \in E \ 0 & (i,j) \not\in E\end{cases}$$,因此其占用的空间是 级别的。

边带权图 ​

对于边带权的图(有一个函数 ),只需要在邻接表里面把这个边权额外存储进去,或者把邻接矩阵的零一改成实数。

BFS ​

Dijkstra 最短路算法和 Prim 最小生成树算法都有用到类似 BFS 的思想。

对于图 ,指定起点 ,BFS 可以计算出 到其他任意节点的距离。BFS 在遍历到距离起点 的节点之前,一定会先遍历到距离 的节点。

不论是有向图还是无向图,在 广度优先树(breadth-first tree) 当中,节点 到 的简单路径,都对应着原图当中 到 的最短路径。

伪代码 ​

  • 表示节点 的状态,黑白灰三种。白表示未处理,灰表示入队,黑表示处理完毕
  • 表示节点 距离起点的距离
  • 表示节点 在广度优先树当中的前驱节点

image

效率分析 ​

  • 初始化需要 时间。
  • 每个节点入队出队一次,每次入队出队需要 时间,总共需要 时间
  • 需要遍历邻接表。邻接表长度 ,需要 时间
  • 故总时间复杂度

DFS ​

伪代码 ​

  • 表示节点 的状态,黑白灰三种。白表示未处理,灰表示正在处理其子树,黑表示处理完毕
  • 表示开始处理的时间戳,是 discovered 的缩写
  • 表示处理完毕后的时间戳,是 finished 的缩写

image

效率分析 ​

  • 初始化需要 的时间
  • 每个节点记录 和 ,总共需要 时间
  • 需要遍历邻接表。邻接表长度 ,需要 时间
  • 故总时间复杂度

括号化定理 ​

在无向图或有向图当中,节点 , 有以下可能的关系

  • 深度优先森林中, 不是 的后代, 也不是 的后代: 与 完全分离
  • 深度优先树中, 是 的后代,
  • 深度优先树中, 是 的后代,

边的分类 ​

一条边 有以下四种分类:

  • 树边 tree edges,表示 是由 直接发现的
  • 后向边 back edges,表示深度优先树中 的祖先是 。有向图的自环也算后向边
  • 前向边 forward edges,表示深度优先树中 的后代是
  • 横叉边 cross edges,表示所有其他类型的边