图的深度优先遍历类似于树的先根遍历,首先访问顶点v0,再访问v0的邻接点v1,同样递归访问v1的邻接点,若到vi时的所有邻接点均以访问完毕,则退回上一个顶点查看是否有邻接点为被访问,若有临界点w未被访问,则访问递归w,否则继续退回前一个结点。全部结点访问完毕时,算法结束。
给出邻接表表示的图的递归和非递归算法,下面是图的邻接矩阵和邻接表表示,设置Visited[i]来记录结点i是否被访问。
#include <stdio.h>
#include <malloc.h>
#define MAXV 50
int visited[MAXV];
typedef int InfoType;
typedef struct
{
int no;
InfoType info;
}VertType;
typedef struct
{
int edges[MAXV][MAXV];
VertType vexs[MAXV];
int n,e;
}MGraph;
typedef struct ANode
{
int adjvex;
InfoType info;
struct ANode *nextarc;
}ArcNode;
typedef int Vertex;
typedef struct
{
Vertex data;
ArcNode *firstarc;
}VNode;
typedef VNode AdjList[MAXV];
typedef struct
{
AdjList adjlist;
int n,e;
}ALGraph;
递归算法如下:
void DFS(ALGraph *G,int v)
{
ArcNode *p;
int n=G->n;
visited[v] = 1;
printf("%3d",v);
p = G->adjlist[v].firstarc;
while(p)
{
if(visited[p->adjvex] == 0)
DFS(G,p->adjvex);
p = p->nextarc;
}
}
非递归算法如下:
void DFS1(ALGraph *G, int v)
{
ArcNode *p;
ArcNode *St[MAXV];
int top=-1;
int i,w,n=G->n;
for(i=0; i<n; i++)
visited[i] = 0;
visited[v] = 1;
printf("%3d",v);
top++;
St[top] = G->adjlist[v].firstarc;
while(top>=0)
{
p = St[top];
top--;
while(p!=NULL)
{
w = p->adjvex;
if(visited[w] == 0)
{
visited[w] = 1;
printf("%3d",w);
top++;
St[top] = G->adjlist[w].firstarc;
break;
}
p = p->nextarc;
}
}
}
void main()
{
MGraph g;
ALGraph *G;
int i,j;
int A[MAXV][6] = {
{0,5,0,7,0,0},
{0,0,4,0,0,0},
{8,0,0,0,0,9},
{0,0,5,0,0,6},
{0,0,0,5,0,0},
{3,0,0,0,1,0}
};
g.n = 6;
g.e =10;
for(i=0; i<g.n; i++)
for(j=0; j<g.n; j++)
g.edges[i][j] = A[i][j];
for(i=0; i<g.n; i++)
visited[i] = 0;
MatToList(g,G);
printf("图G的邻接表:\n");
DispList(G);
printf("从顶点0开始的DFS(递归算法):\n");
DFS(G,0);
printf("\n");
printf("从顶点0开始的DFS(非递归算法):\n");
DFS1(G,0);
printf("\n");
}
运行结果: