目录
一.题目描述
深度优先搜索遍历类似于树的先根遍历,是树的先根遍历的推广。其过程为:假设初始状态是图中所有顶点未曾被访问,则深度优先搜索可以从图中的某个顶点v出发,访问此顶点,然后依次从v的未被访问的邻接点出发深度优先遍历图,直至图中所有和v有路径相通的顶点都被访问到;若此时图中尚有顶点未被访问,则另选图中一个未曾被访问的顶点作为起始点,重复上述过程,直至图中所有顶点都被访问到为止。
其算法可以描述如下:
在本题中,读入一个无向图的邻接矩阵(即数组表示),建立无向图并按照以上描述中的算法遍历所有顶点,输出遍历顶点的顺序。
输入
输入的第一行包含一个正整数n,表示图中共有n个顶点。其中n不超过50。
以后的n行中每行有n个用空格隔开的整数0或1,对于第i行的第j个0或1,1表示第i个顶点和第j个顶点有直接连接,0表示没有直接连接。当i和j相等的时候,保证对应的整数为0。
输入保证邻接矩阵为对称矩阵,即输入的图一定是无向图。
输出
只有一行,包含n个整数,表示按照题目描述中的深度优先遍历算法遍历整个图的访问顶点顺序。每个整数后输出一个空格,并请注意行尾输出换行。
样例输入
4
0 1 0 1
1 0 0 0
0 0 0 1
1 0 1 0
样例输出
0 1 3 2
二.代码实现
#include <iostream>
#include <iomanip>
#include <cstdio>
using namespace std;
#define MVNum 100 //最大顶点数
typedef string VerTexType; //假设顶点的数据类型为字符串
typedef int ArcType; //假设边的权值类型为整型
bool visited[MVNum];//访问标志数组
//Status (* VisitFunc)(int v);//函数变量
//------------图的邻接矩阵------------------
typedef struct {
VerTexType vexs[MVNum]; //顶点表
ArcType arcs[MVNum][MVNum]; //邻接矩阵
int vexnum, arcnum; //图的当前vexnum点数和arcnum边数
} Graph;
//得到顶点i的数据
VerTexType Vertexdata(const Graph &g, int i)
{
return g.vexs[i];
}
int LocateVex(const Graph &g, VerTexType v) //返回定点所示的下标
{
//确定点v在G中的位置
for(int i = 0; i < g.vexnum; ++i)
if(g.vexs[i] == v)
return i;
return -1;
}//LocateVex
int FirstAdjVex(const Graph &g, int v)
{
//返回v的第一个邻接点编号,没有返回-1
/****在此下面完成代码***************/
int i,j;
for(i=v;i<g.vexnum;i++)
{
for(j=0;j<g.vexnum;j++)
{
if(g.arcs[i] [j]== 1)
return j;
}
}
return -1;
/***********************************/
}//FirstAdjVex
int NextAdjVex(const Graph &g, int v, int w)
{
//返回v相对于w的下一个邻接点,没有返回-1
/****在此下面完成代码***************/
int i,j;
for(i=w+1;i<g.vexnum;i++){
if(g.arcs[v][i] == 1)
return i;
}
return -1;
/***********************************/
}//NextAdjVex
void CreateUDG(Graph &g)
{
//采用邻接矩阵表示法,创建无向图G
/****在此下面完成代码***************/
int i,j,k;
string v1,v2;
cin >> g.vexnum ;//是图的总顶点数n
//构造邻接矩阵
for(i=0;i<g.vexnum;i++)
{
for(j=0;j<g.vexnum;j++)
cin >> g.arcs[i][j];
}
/***********************************/
}//CreateUDN
void DFS(Graph g, int v) //从第v个顶点出发,深度优先遍历g
{
int w;
cout << v << " ";
visited[v]=true; // 访问第v个顶点,并置访问标志数组相应分量值为true
//VisitFunc(v);
//依次检查v的所有邻接点w,FirstAdjVex(g,v)表示v的第一个邻接点
//NextAdjVex(g,v,w)表示v的下一个邻接点 w>=0;表示存在邻接点
for(w=FirstAdjVex(g,v); w>=0; w=NextAdjVex(g,v,w))
{
if(!visited[w]) DFS(g,w);
//对v尚未访问的邻接顶点w递归调用DFS
}
}
void DFSTraverse(Graph g)
{
int v;
//VisitFunc = Visit;
for ( v=0; v<g.vexnum; v++ ) visited[v]=false;
for ( v=0; v<g.vexnum; v++ )
if(!visited[v]) DFS(g,v);
}
void DestroyUDG(Graph &g)
{
//you should do this
g.arcnum=g.vexnum=0;//点和边都设置为0,则此矩阵为零
}
int main()
{
Graph g;
CreateUDG(g);
DFSTraverse(g);
DestroyUDG(g);
return 0;
}//main