算法复习——图算法篇之深度优先搜索
以下内容主要参考中国大学MOOC《算法设计与分析》,墙裂推荐希望入门算法的童鞋学习!
1. 问题回顾
图的搜索
- 数组结构
- 查询最大值:简单循环搜索所有元素,记录最大值
- 图结构
- 查询相邻顶点:简单循环搜索各顶点关联的边
- 查询可达顶点:简单循环搜索,不能找到全部可达顶点!
因此,我们需要按照特定的次序搜索顶点,于是引出了两种搜索策略:广度优先搜索和深度优先搜索。广度优先搜索可参考算法复习——图算法篇之广度优先搜索。
2. 算法思想
走迷宫问题
算法步骤
- 分叉时,任选一条边深入
- 无边时,后退一步找新边(回溯)
- 找到边,从新边继续深入
辅助数组
-
c
o
l
o
r
color
color:用颜色表示顶点状态
- W h i t e White White:白色顶点尚未被发现
- B l a c k Black Black:黑色顶点已被处理
- G r a y Gray Gray:正在处理,尚未完成
- p r e d pred pred:顶点 u u u由 p r e d [ u ] pred[u] pred[u]发现
- d d d:顶点发现时刻(变成灰色的时刻)
- f f f:顶点完成时刻(变成黑色的时刻)
3. 伪代码
DFS(G)
输入:图 G G G
输出:祖先数组 p r e d pred pred,发现时刻 d d d,结束时刻 f f f
新建数组color[1..V], pred[1..V], d[1..V], f[1..V]
// 初始化
for v ∈ V do
pred[v] ← NULL
color[V] ← WHITE
end
time ← 0
for v ∈ V do
if color[v] == WHITE then
DFS-Visit(G, v)
end
end
return pred, d, f
DFS-Visit(G, v)
输入:图G,顶点v
color[v] ← GRAY
time ← time + 1
d[v] ← time
for w ∈ G.Adj[v] do
if color[w] == WHITE then
pred[w] ← v
DFS-Visit(G, w)
end
end
color[v] ← BLACK
time ← time + 1
f[v] ← time
时间复杂度分析:
搜索顶点 v v v的开销为 O ( 1 + ∣ A d j [ v ] ∣ ) O(1+|Adj[v]|) O(1+∣Adj[v]∣),每个顶点只搜索一次,共 ∣ V ∣ |V| ∣V∣次,所以整体算法的时间复杂度是 O ( ∑ v ∈ V ( 1 + ∣ A d j [ v ] ∣ ) ) = O ( ∣ V ∣ + ∑ v ∈ V ∣ A d j [ v ] ∣ ) = O ( ∣ V ∣ + ∣ E ∣ ) O(\sum_{v \in V}(1+|Adj[v]|))=O(|V|+\sum_{v \in V}|Adj[v]|)=O(|V|+|E|) O(∑v∈V(1+∣Adj[v]∣))=O(∣V∣+∑v∈V∣Adj[v]∣)=O(∣V∣+∣E∣)。
4. 算法性质
4.1 深度优先树
4.1.1 无向图
连通无向图通过深度优先搜索得到了一棵深度优先树,它是顶点以前驱为祖先形成的数;如果是非连通无向图图,得到的则是深度优先森林。
无向图深度优先树的边具有以下性质:
-
在深度优先树中的边称为树边
-
后向边不是树边,但两顶点在深度优先树中是祖先后代关系
-
对于无向图,非树边一定是后向边
- 证明:从顶点
v
v
v,搜索顶点
w
w
w
- 若 w w w为白色, ( v , w ) (v, w) (v,w)为树边
- 若 w w w为灰色, ( v , w ) (v, w) (v,w)为后向边
- w w w不可能是黑色,因为在 w w w变黑前一定已经搜索过 v v v了。
- 证明:从顶点
v
v
v,搜索顶点
w
w
w
4.1.2 有向图
在连通无向图的深度或广度优先树中,树的形状取决于搜索顺序,树的数量一定是1棵优先树;而在连通有向图的深度或广度优先树中,树的形状于搜索顺序,树的数量也取决于搜索顺序。
4.1.3 深度优先搜索边的分类
- 无向图,深度优先搜索有2类边
- 树边:在深度优先树中的边
- 后向边:两顶点有祖先后代关系的非树边
- 有向图,深度优先搜索有4类边
- 树边:在深度优先树中的边
- 前向边:不在深度优先树中,从祖先指向后代的边
- 后向边:从后代指向祖先的边
- 横向边:顶点不具有祖先后代关系的边
4.2 括号化定理
- 点的性质
- 点 v v v发现时刻和结束时刻构成区间 [ d [ v ] , f [ v ] ] [d[v], f[v]] [d[v],f[v]]
- 任意两点
v
,
w
v, w
v,w必满足以下情况之一:
- [ d [ v ] , f [ v ] ] [d[v], f[v]] [d[v],f[v]]包含 [ d [ w ] , f [ w ] ] [d[w], f[w]] [d[w],f[w]], w w w是 v v v的后代
- [ d [ w ] , f [ w ] ] [d[w], f[w]] [d[w],f[w]]包含 [ d [ v ] , f [ v ] ] [d[v], f[v]] [d[v],f[v]], v v v是 w w w的后代
- [ d [ v ] , f [ v ] ] [d[v], f[v]] [d[v],f[v]]和 [ d [ w ] , f [ w ] ] [d[w], f[w]] [d[w],f[w]]完全不重合, v v v和 w w w均不是对方后代
- 证明(不妨设
d
[
v
]
<
d
[
w
]
d[v]<d[w]
d[v]<d[w])
- 若 f [ v ] > d [ w ] f[v]>d[w] f[v]>d[w]: w w w被发现时, v v v为灰色,所以 w w w是 v v v的后代
- 若 f [ v ] < d [ w ] f[v]<d[w] f[v]<d[w]: w w w被发现时, v v v为黑色,所以 v v v和 w w w均不是对方后代
4.3 白色路径定理
- 在深度优先树中,顶点 v v v是 w w w的祖先等价于在 v v v被发现前,从 v v v到 w w w存在全为白色顶点构成的路径
- 证明(基本思想)
- 充分性:由括号化定理, v v v在发现之前,其后代全为白色
- 必要性: v v v刚被发现时,路径上除 v v v以外的点仍都为白色,按深度优先搜索特点,一定会搜索路径上的所有点