广度优先搜索——算法始终将已发现节点和未发现结点之间的边界【已访问,但其后继结点没有遍历完】,沿其广度方向向外扩展
将每个结点涂上白色、灰色或黑色,所有结点在一开始的时候均为白色;凡是灰色和黑色的结点都是已被发现的结点,但会加以区分
如果边(u, v)属于E且结点u是黑色,则v既可能是灰色也可能是黑色,即与黑色结点邻接的结点都已经被发现
对于灰色结点,其邻接结点可能存在未被发现的八色结点
灰色结点所代表的就是已知和未知两个集合之间的边界
下面遍历源结点为s的图,对于一个结点u,u.color表示其颜色,u.p表示其前驱,u.d表示u到源结点的距离
使用一个队列Q来管理灰色结点
BFS(G, s)
for each vertex u 属于 G.V - {s}
u.color = WHITE
u.d = INF
u.p = NIL
s.color = GRAY
s.d = 0
s.p = NIL
//上面的步骤为初始化
Q = 空集
ENQUEUE(Q, s)
//初始队列中只有源结点
while(Q != 空集)
u = DEQUEUE(Q)
for each v 属于 G.adj[u]
v.p = u
v.d = u.d + 1
v.color = GRAY
ENQUEUE(v)
u.color = BLACK
//遍历结束后,结点颜色为黑色
深度优先搜索——总是对最近才发现的结点v的出发边进行探索,直到该结点的所有出发边都被发现为止;一旦结点v的所有出发边都被发现,则“回溯”到v的前驱结点,搜索该前驱结点的其他出发边。该过程一直持续直到从源结点可以达到的所有结点都被发现为止。
同样的,所有结点的初始颜色为白色,在结点被发现后变为灰色,在其邻接链表被扫描完成后变为黑色
不同的是,每个结点上有两个时间戳,v.d记录结点第一次被发现的时间,v.f记录对v的邻接链表扫描结束的时间
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
DFS-VISIT(G, u)
DFS-VISIT(G, u)
time = time + 1
u.d = time
u.color = GRAY
for each v 属于 G.Adj[u]
if v.color == WHITE
v.p = u
DFS-VISIT(G, v)
u.color = BLACK
time = time + 1
u.f = time