编辑于 2020年10月2日20点45分 关于后向边和前向边的一些概念问题的补充说明
深度优先搜索:总是对最近才发现的节点v的出发边进行探索,直到该节点的所有出发边都被发现为止。一旦某个节点v的出发边都被发现,搜索则回溯到v的前驱节点。
如果还存在尚未发现的节点,则深度优先搜索将这些未被发现的节点中任选一个作为新的源节点。并重复该过程,直到所有节点都被发现。
注意:可以看到,在此处的限定条件是直到所有的节点都被发现为止,这也是深度优先搜索与广度优先搜索不同的地方,由于广度优先搜索常常用来寻找从特定源节点出发的最短路径,而深度优先算法则常常作为另一个算法中的子程序。
正由于深度优先搜索的这个性质,其形成的前驱子图也与广度优先搜索形成的不同,因为前者可以通过源节点形成多棵树。
前驱子图(In DFS):对于图G =(V, Ep),其中Ep = {(v.p, v): v∈V且v.p≠NIL}。深度优先搜索的前驱子图形成一个由多棵深度优先树构成的深度优先森林,森林Ep的边仍然被称为树边。
时间戳:DFS对于每个节点v来说,都有两个时间戳:第一个v.d记录节点v第一次被发现的时间,第二个v.f则记录完成对v的邻接链表完成扫描的时间。
显然,对于同一个节点的d和f来说,有: u.d<u.f。
以下是伪代码实现,其中time是实现时间戳的一个全局变量。我们应当关心的是其应该在什么时间增加:
在代码中,有两个增加的时间:
1、每当扫描到一个白色的节点的时候,增加1,并将该白色节点的u.d赋为增加后的time。
2、没当对某个节点的邻接链表进行充分的扫描后,增加1,并将该灰色节点的u.f赋为增加后的time。
DFS(G)
{
for each vertex u ∈ G.V
u.color = WHITE;
u.p = NIL;
time = 0;
for each vertex u ∈ G.V
if(u.color = WHITE) //在这个函数中找到的color = WHITE 的节点为每一次搜索的源节点
DFS-VISIT(G, u);
}
DFS-VISIT(G, u) // 这是一个递归函数
{
time = time + 1;
u.d = time;
u. color = GRAY;
for each v∈G:Adj[v]
//在对某个节点进行深度