【数据结构】ZJNU1011 实验五 图的建立与遍历

200 阅读2分钟

​本文已参与「新人创作礼」活动,一起开启掘金创作之路。

Description

按邻接矩阵的方法创建图,分别用深度优先和广度优先方法遍历图。

Input

输入的数据有多组
对于每组测试数据第一行为图中点的个数n(0 < n < 100)与边的数量m(m < =10000)。
接下来有m行,每行两个整数a,b(0 <=a,b < n),代表这a,b这两个点之间是连通的。

Output

分别输出按照深度优先搜索与广度优先搜索方法遍历的结果,每个输出结果后面都有一空行。

Sample Input

3 0

5 3

0 1

0 4

1 3

Sample Output

0 1 2

0 1 2

0 1 3 4 2

0 1 4 3 2

Hint

存储图的邻接矩阵的数据结构要定义成全局变量,否则会出运行时错误(runtime error)。

代码区:

#include <cstdio>
#include <string.h>
#include <algorithm>
#include <queue>
#include <iostream>
using namespace std;
int map[105][105];//邻接矩阵数组
int vis[1105];//是否输出过的标记
void bfs(int p,int n)//广度优先搜索
{
  	int i;
  	queue<int>qu;// 定义队列
  	qu.push(p);//将u推入队列
  	while(!qu.empty())//当qu队列非空时,继续进行bfs搜索
	{
  		int tmp = qu.front();//将队列的对头提取出来
		//因为队列是遵从先入先出的规则,所以要先拿对头
  		vis[tmp]=1;//标记该元素,以免再次输出他
  		qu.pop();//将已经得到信息的对头弹出,以便下次搜索对头下一个元素
  		cout << tmp << ' ' ;//输出对头元素值
  		for(i=0;i<n;i++)//从最小的元素0开始查找
		{
  			if(i==tmp) continue;//当i等于对头时退出当次循环,因为已经搜索过了
  			if(map[tmp][i]&&!vis[i])//寻找与tmp元素联通的值并且该值没有搜索过
			{
  				vis[i]=1; //标记找过了
  				qu.push(i);//将该数推入队列,进入循环
  			}
  		}
  	}
}
void dfs(int p, int n)//深度优先搜索
{
  	int i;
  	vis[p]=1;//标记查找过了
  	cout << p << ' ';//输出该数
  	for(i=0;i<n;i++)
  	{
  		if(i==p)
  			continue;//同上,找过该数了所以跳过
  			if(map[p][i]>0&&!vis[i])//寻找与tmp元素联通的值并且该值没有搜索过
  			{
  				dfs(i,n);//进行递归调用,直到没有与该数连通的数为止
  			}
  	}
}
int main()
{
  	int n,m;
	int a,b,i,j;
  	while(cin >> n >> m)//输入点的个数和边的个数
  	{
		memset(map,0,sizeof(map));//数组初始化
  	 	for(j=0;j<m;j++)
  	 	{
  			cin >> a >> b ;//输入连通的两个点
  			map[a][b]=1;//因为邻接矩阵是通过斜对角线对称的。所以这两个都赋值为1
			map[b][a]=1;
  	 	}	
  		memset(vis,0,sizeof(vis));//数组初始化
  		for(i=0;i<n;i++)
  		{
  	 		if(!vis[i])//当没有搜索过时
  	 		dfs(i,n);//深度优先搜索
  		}
  		cout << endl;
  		memset(vis,0,sizeof(vis));//vis数组又要初始化因为经历过一次dfs搜索,vis数组需要重新归零
  		for(i=0;i<n;i++)
		{
  			if(!vis[i]) //当没有搜索过时
			{
  				bfs(i,n);//广度优先搜索
  			}
  		}
		cout << endl << endl;
  	}
  	return 0;
}

新手上路,有错请指正