对图的遍历方式,我总是觉得BFS比DFS要易于理解,因此我也总是倾向于使用BFS去解决问题。但是,DFS具有在某些场景中(如求解可能的路径)比BFS更有优势,到最后也是逃不过递归的命。

以下是《算法导论》中给出的图的DFS伪码:



DFS(G)
for each vertex u in G.V
u.color = WHITE
u.pre = NIL
time = 0
for each vertex u in G.V
if u.color == WHITE
DFS-VISIT(G, u)

DFS-VISIT(G, u)
time = time + 1
u.d = time
u.color = GRAY
for each v in G:Adj[u]
if v.color == WHITE
v.pre = u;
DFS-VIST(G, v)
u.color = BLACK
time = time + 1
u.f = time


深度优先搜索算法在搜索过程中对节点进行涂色来指明节点的状态。每个节点的初始颜色都为白色(WHITE),在节点被发现后变为灰色(GRAY),在其邻接链表被扫描完成后变为黑色。

深度优先搜索还在每个节点盖上一个时间时间戳。每个节点v有两个时间戳:第一个时间戳v.d记录节点v第一次被发现的时间(涂上灰色的时间),第二个时间戳v.f记录完成对v的邻接表扫描的时间(图上黑色的时间)。这些时间戳通常能够帮助推断深度优先搜索算法的行为。

深度优先搜索的时间复杂度为O(V + E),V为节点的数量,E为边的数量。

关于更多深度优先搜索算法及其性质的介绍可详细阅读《算饭导论》22.3节。也可做几道LeetCode上的相关题目加深理解和运用。


作者:凸云​,转载请注明原文链接​