两种写法的区别就是for循环的处理方式的区别,仔细观察分析
第一种写法
void AMG_DFS_stack(AMGraph * g, void (*visit)(VertexType), int v0)
{
bool * visited = new bool[g->vexnum];
memset(visited, false, sizeof(bool));
stack<INDEX> s;
visit(g->vexs[v0]);
visited[v0] = true;
s.push(v0);
// 栈空说明已从最后一个节点回溯到了第一个节点
while(!s.empty())
{
for(int i=0;i<g->vexnum;)
{
int top = s.top();
// 如果有未访问过的邻接点
if(visited[i] == false && g->arcs[top][i] == 1){
visit(g->vexs[i]);
visited[i] = true;
/* 将i处结点入栈后,并使得循环变量i为0,使得本次循环结束之后,
下一次循环从头开始遍历刚才入栈的结点的可能邻接点(妙)*/
s.push(i);
i = 0;
}
else
i++;
}
// for循环结束说明一条道已经走到头了,需要出栈回溯
s.pop();
}
}
第二种写法
void AMG_DFS_stack2(AMGraph * g, void (*visit)(VertexType), int v0)
{
stack<INDEX> S;
vector<bool> visited(g->vexnum, false);
visit(g->vexs[v0]);
visited[v0] = true;
S.push(v0);
while(!S.empty())
{
int top = S.top();
int i;
for(i = 0;i<g->vexnum;++i)
{
// // 如果有未访问过的邻接点
if(visited[i] == false && g->arcs[top][i] == 1)
{
visit(g->vexs[i]);
visited[i] = true;
/* 找到了未访问过的邻接点,将其入栈,并结束for循环以终止遍历当前结点的邻接点,
转到下一次while循环以遍历刚才入栈的结点的邻接点 */
S.push(i);
break;
}
}
// 如果栈顶结点没有未访问过的邻接点,说明一条路走到头了,需要出栈回溯
if(i == g->vexnum)
S.pop();
}
}