- 深度优先遍历
1)思路:选出起始顶点v,然后选取与v邻接的一个顶点u(u未被访问过),访问u,让后重复上述操作,继续选取u的一个未访问过的顶点x,访问后继续重复,直至选取的某个点没有未访问过的邻接点了,退回到最近一次访问过的点, 选取下一个未访问过的邻接点,以此类推。
2)递归描述:选取起始顶点v,访问,选取它的一个邻接点,若未访问过,则进行递归遍历,如此可访问与v连通的所有点。
3)非连通处理:若访问完v的所有连通的点后,仍有未访问过的点,选取下一个为访问过的点作为起始点,重新进行递归遍历操作。
4)代码实现:
Status DFS(MGraph &G,int v,Status (*Visit)(ElemType))
{
//遍历一个连通分量,不限定图的存储结构,v为起始点下标(注意,DFS不能遍历一整个非连通图,只能遍历一个连通分量)
Visit(v);
visited[v] = true;
//w是v的邻接点,第一次先找到v的第一个邻接点,进行dfs,在w的
//所有邻接点都找到了后,返回到v这一层,再找v的第二个邻接点,以此类推
for(int w = FirstAdjVex(G,v); w >= 0; w = NextAdjVex(G,w))
{
if(!visited[w])
DFS(G,w,Visit);
}
}
Status DFSTraverse(MGraph &G,int v,Status (*Visit)(int v))
{
for(v = 0;v < G.vexnum; ++v)
{
visited[v] = false;//表示所有顶点都为被访问过
}
//因为可能此图是一个非连通图,如果要遍历所有的点,在遍历完一个连通分量之后,需要再遍历另一个连通分量
for(v = 0; v < G.vexnum; ++v)
{
if(!visited[v])
DFS(G,v,Visit);//注意这里把函数作为参数是怎么传递的
}
}
2.广度优先搜索
1)思路:选取一个起始点v,逐个遍历v的邻接点,直至把v的所有邻接点都遍历了一遍,再从v的第一个邻接点开始,逐个访问v的第一个邻接点的所有邻接点,重复上述操作,直至遍历完与v连通的所有点。
2)分析:用队列存储访问过的元素,v是起始点,访问v,v入队,循环判断条件只要队列不为空,取出队列头元素,访问其邻接点并将邻接点入队,重复上述操作,直至队列为空,也就遍历完了与v连通的所有点。
3)非连通处理:遍历完v所属的连通分量,若仍有点未访问,从从其开始,重新进行广度优先搜索。
4)代码实现:
Status BFS(MGraph &G,int v,Status (*Visit)(ElemType))
{
Visit(V);
visited[v] = true;
EnQueue(Q,v);
//队列不为空
while(!IsEmpty(Q))
{
ElemType u;
DeQueue(Q,u);
for(ElemType w = FirstAdjNex(G,u);w >= 0; w = NextAdjVex(G,u,w))//NextAdjVex找除w外的邻接点
{
if(!visited[w])
{
Visit(w);
visited[w] = true;
EnQueue(Q,w);
}
}
}
}
Status BFSTraverse(MGraph &G,Status (*Visit)(int v))
{
//不管是dfs,还是bfs,都需要初始化visited数组为false
for(v = 0; v < G.vexnum; ++v)
{
visited[v] = false;
}
for(v = 0; v < G.vexnum; ++v)
{
if(!visited[v])
BFS(G,v,Visit);
}
}