图的遍历

什么是图?
简单地说,图就是有一些小圆点(称作顶点)和连接这些原点的直线(称为边)组成的。如图就是一个简单的图,由顶点(①,②,③,④,⑤)和边(1-2,1-3,2-3,2-4,3-5)组成。
图的遍历_第1张图片图的遍历就是指把图的每一个顶点都访问一次。如果使用深度优先搜索来遍历该图得到的结果就是
图的遍历_第2张图片并将访问顺序定义为时间戳,如下。
图的遍历_第3张图片深度优先遍历的主要思想就是:首先以一个未被访问过的顶点作为起始顶点,沿当前顶点的边走到未被访问过的顶点;当没有顶点是,则回到上一个顶点,继续试探访问别的顶点,直到所有顶点都被访问。那么如何用代码实现此过程呢?首先需要用一个二维数组map来存储一个图
图的遍历_第4张图片上图二维数组,第i行第j列表示顶点i到顶点j是否右边,1表示有边,∞表示无边,将i==j设为0。这种存储方法叫做图的邻接矩阵存储法
接下来就是用深搜来实现遍历了。

void dfs(int cur)//cur表示顶点所在的编号
{
	printf("%d ",cur);
	sum++;//每访问一个顶点sum就加一
	if(sum==n) return;//sum==n表示所有的顶点都被访问过,所以退出
	for(i=1;i<=n;++i){
		if(map[cur][i]==1 && book[i]==0){//判断当前cur顶点到顶点i是否右边,且判断i是否被访问
			book[i]=1;//标记i表示访问过
			dfs(i);//从i开始往下遍历
		}
	}
	return;
}

完整代码如下。

#include 
int book[101],sum,n,map[101][101];
void dfs(int cur)//cur表示顶点所在的编号
{
	int i;
	printf("%d ",cur);
	sum++;//每访问一个顶点sum就加一
	if(sum==n) return;//sum==n表示所有的顶点都被访问过,所以退出
	for(i=1;i<=n;++i){
		if(map[cur][i]==1 && book[i]==0){//判断当前cur顶点到顶点i是否右边,且判断i是否被访问
			book[i]=1;//标记i表示访问过
			dfs(i);//从i开始往下遍历
	}
}
return;
}

int main()
{
	int i,j,m,a,b;
	scanf("%d %d",&n,&m);
	for(i=1;i<=n;++i){
		for(j=1;j<=m;++j){
			if(i==j) map[i][j]=0;
			else map[i][j]=99999999;//99999999代表∞ 
	}
}

for(i=1;i<=m;++i){
	scanf("%d %d",&a,&b);
	map[a][b]=1;
	map[b][a]=1;//无向图需要将map[b][a]也赋值1 
}

book[1]=1;
dfs(1);

return 0;
}

输入数据验证

5 5
1 2
1 3
2 4
2 3
3 5

运行结果如下:

1 2 3 5 4

以上就是深度优先遍历的过程,而使用广度优先遍历这个图的结果如下。
图的遍历_第5张图片同样以一个未被访问过的点作为起始顶点,如1号顶点,将其放入队列中,然后将与1号顶点相邻的顶点2,3放入队列中然后将2号,相邻的4号,3号相邻的5号放入队列,所有顶点都被访问,遍历结束。
广度优先遍历的主要思想是:首先以一个未被访问过的顶点作为其实顶点,访问其所有相邻的顶点,然后对每隔相邻的顶点,访问与他们相邻的顶点,知道所有顶点都被访问。代码如下。

#include 
int main()
{
	int i,j,n,m,a,b,cur,book[101]={0},map[101][101];
	int que[100001],head,tail;
	scanf("%d %d",&n,&m);//初始化 
	for(i=1;i<=n;++i){
		for(j=1;j<=m;++j){
			if(i==j) map[i][j]=0;
			else map[i][j]=99999999;//99999999表示∞ 
	}
}

//读入顶点之间的边 
for(i=1;i<=m;++i){
	scanf("%d %d",&a,&b);
	map[a][b]=1;
	map[b][a]=1;//无向图map[b][a]也要赋值 
}

//初始化队列 
head=1;
tail=1;

que[tail++]=1;//从1号出发 
book[1]=1;

while(headn) break;//tail>n,表明所有的点被访问过,此时退出 
	head++;//顶点拓展结束head++才能继续向下拓展 
}

for(i=1;i

输入数据进行验证。

5 5
1 2
1 3
2 3
2 4
3 5

运行结果如下:

1 2 3 4 5

谢谢大家!

你可能感兴趣的:(图的遍历)