本文已参与「新人创作礼」活动,一起开启掘金创作之路。
5-8 深度优先遍历邻接表存储的图
DFS 思想:
深度优先遍历图的方法是,从图中某顶点v出发:
1.访问顶点v;
2.依次从v的未被访问的邻接点出发,对图进行深度优先遍历;直至图中和v有路径相通的顶点都被访问;
3.若此时图中尚有顶点未被访问,则从一个未被访问的顶点出发,重新进行深度优先遍历,直到图中所有顶点均被访问过为止。
DFS伪代码:
DFS(当前被访问的节点pos)
{
pos被标记访问过
遍历与pos相连的节点(有边相连)
如果这个节点没有被访问过
搜索(DFS)当前节点
}
思路:这道题的关键是理解深度优先遍历时额外设定的visited[]数组的作用:用来标记是否访问过这个结点,从而确定遍历时是否回退。
题目代码:
typedef int Vertex;
typedef struct AdjNode {
Vertex AdjV;
struct AdjNode *Next;
struct AdjNode *FirstEdge;
}AdjVNode;
typedef struct {
AdjVNode G[MAX];
}Graph;
typedef Graph* LGraph;
/* 邻接表存储的图 - DFS */
bool Visited[MAX];
typedef AdjVNode* PtrToAdjVNode;
void Visit( Vertex V )
{
printf("正在访问顶点%d\n", V);
}
/* Visited[]为布尔类型的全局数组,已经初始化为false */
void DFS( LGraph Graph, Vertex V, void (*Visit)(Vertex) ) //Graph表示邻接矩阵存储的图 V表示当前访问的节点 第三个参数为输出节点的函数
{
PtrToAdjVNode W;
Visit(V); //访问V时打印访问的顶点
Visited[V]=true; //标记V被访问过,此后不再访问
for( W=Graph->G[V].FirstEdge; W; W=W->Next )
if ( !Visited[W->AdjV] ) //如果当前节点V与遍历的节点w有边相连,且w没有被访问过
DFS(Graph,W,Visit); //从W开始搜索访问
}
5-9 基于邻接矩阵表示的深度优先遍历
思路:这道题给的代码很全,比较简单。
#include <stdio.h>
#define MVNum 100
typedef struct{
char vexs[MVNum];
int arcs[MVNum][MVNum];
int vexnum,arcnum;
}AMGraph;
int visited[MVNum];
void CreateUDN(AMGraph &G);//实现细节隐藏
void DFS(AMGraph G, int v){
printf("%c ",G.vexs[v]); visited[v] =1;
int w;
for(w = 0; w < G.vexnum; w++)
if((visited[w]==0)&&(arcs[v][w]==1)) //visited[w]==0判断是否访问过,arcs[v][w]==1判断v和w之间有没有边存在
DFS(G, w);
}
void DFSTraverse(AMGraph G){
int v;
for(v = 0; v < G.vexnum; ++v)
visited[v] = 0;
for(v = 0; v < G.vexnum; ++v)
if(!visited[v]) //!visited[v]判断是否访问过
DFS(G,v);
}
int main(){
AMGraph G;
CreateUDN(G);
DFSTraverse(G);
return 0;
}