编写程序对给定的有向图(不一定连通)进行深度优先遍历,图中包含n个顶点,编号为0至n-1。本题限定在深度优先遍历过程中,如果同时出现多个待访问的顶点,则优先选择编号最小的一个进行访问,以顶点0为遍历起点。
输入格式:
输入第一行为两个整数n和e,分别表示图的顶点数和边数,其中n不超过20000,e不超过50。接下来e行表示每条边的信息,每行为两个整数a、b,表示该边的端点编号,但各边并非按端点编号顺序排列。
输出格式:
输出为一行整数,每个整数后一个空格,即该有向图的深度优先遍历结点序列。
输入样例1:
3 3
0 1
1 2
0 2
输出样例1:
0 1 2
输入样例2:
4 4
0 2
0 1
1 2
3 0
输出样例2:
0 1 2 3
题解:
#include <stdio.h>
#include <stdlib.h>
#define MAXLEX 20000
int visited[MAXLEX]; //记录访问过的节点
typedef int VertexType;
typedef struct node
{
int adjvex; //
struct node *next;
}EdgeNode; //定义邻接表边节点
typedef struct vnode
{
VertexType vertex; //节点域
EdgeNode *firstegde; //节点头指针
}VertexNode; //定义邻接表头节点
typedef VertexNode AdjList[MAXLEX]; //定义由顶点构成的结构体数组
typedef struct
{
AdjList adjlist;
int n,e; //顶点数和边数
}ALGraph; //顶点表
//有向图
void CreatGraphAL(ALGraph *G)
{
int i,j,k;
EdgeNode *s;
scanf("%d %d",&G->n,&G->e); //输入顶点数n和边数e
for(i=0;i<G->n;i++)
{
G->adjlist[i].vertex=i;
G->adjlist[i].firstegde=NULL;
} //顶点表数据域填值初始化顶点表指针域
//输入边信息构造邻接表
for(k=0;k<G->e;k++)
{
scanf("%d %d",&i,&j);
s=(EdgeNode*)malloc(sizeof(EdgeNode));
s->adjvex=j; //填上坐标
EdgeNode *p=G->adjlist[i].firstegde; //头插法
s->next=G->adjlist[i].firstegde;
G->adjlist[i].firstegde=s;
} //输入边信息
for(i=0;i<G->n;i++)
{
int t=0;
EdgeNode* p=G->adjlist[i].firstegde;
while(p!=NULL)
{
if(p->next!=NULL)
{
if((p->adjvex)>(p->next->adjvex))
{
t=p->adjvex;
p->adjvex=p->next->adjvex;
p->next->adjvex=t;
}
}
p=p->next;
} //用冒泡排序调整表节点次序
}
}
//深度优先遍历
void DFS(ALGraph *G,int i)
{
int j;
EdgeNode *p;
printf("%d ",G->adjlist[i].vertex); //访问当前节点并输出
visited[i]=1; //标记当前节点为已访问
p=G->adjlist[i].firstegde;
while(p!=NULL)
{
if(visited[p->adjvex]==0) //邻节点没被访问过就递归调用DFS
{
DFS(G,p->adjvex);
}
p=p->next; //查找完后向后移动
}
}
void DFST(ALGraph *G)
{
int i;
for(i=0;i<G->n;i++)
{
visited[i]=0;
} //初始化标志数组
for(i=0;i<G->n;i++)
{
if(!visited[i])
{
DFS(G,i);
}
}
}
int main()
{
ALGraph graph;
CreatGraphAL(&graph);
DFST(&graph);
return 0;
}