该文章主要介绍两种常用的图搜索方式。
一、广度优先搜索
1.策略
首先访问顶点s,之后访问所有s的邻接顶点,再访问s邻接顶点的邻接顶点…多次访问后,图中所有顶点均被访问一次,则遍历过程结束。
该遍历方法类似于二叉树中的层次遍历。
2.代码
与层次遍历相似,图的广度优先遍历也使用队列作为辅助。
template <typename Tv, typename Te>
void Graph<Tv, Te>::BFS(int v,int & clock)
{
Queue<int> Q;
status(v) = DISCOVERED;
Q.enedueue(v);
while(!Qempty())
{
int v = Q.dequeue();
dTime(v) = ++clock;
for(int u = firstNbr(v);-1 < u;u = nextNbr(v, u))
if(UNDISCOVERED == status(u))
{
status(u) = DISCOVERED;
Q.enqueue(u);
status(v, u) = TREE;
parent(u) = v;
}
else
status(v,u) = CROSS;
status(v) = VISITED;
}
}
二、深度优先搜索
1.策略
首先访问顶点S: DFS(S),若存在未被访问的邻居U,则递归执行DFS(U),否则返回。
2.代码
template <typename Tv, typename Te>
void Graph <Tv, Te>::DFS(int v, int & clock)
{
dTime(v) = ++clock;
status(v) = DISCOVERED;
for (int u = firstNbr(v); -1 < u; u = nextNbr(v, u))
switch(status(u))
{
case UNDISCOVERED:
status(v, u) = TTREE;
parent = v;
DFS(u, clock);
break;
case DISCOVERED:
status(v, u) = BACKWARD;
break;
default:
status(v, u) = dTime(v) < dTime(u) ? FORWARD : CROSS;
break;
}
status(v) = VISITED;
fTime(v) = ++clock;
}