第六章学习 列出连通集
这一章主要是学习了图的结构和应用,而作业里列出连通集的题则是对BFS(宽度优先)和DFS(深度优先)两种搜索方法的应用
下面 先分别介绍这两种搜索方法
(1)DFS
从图中某个顶点v出发,访问v → 找出刚访问过的顶点的第一个未被访问的邻接点,访问该顶点,再以该顶点为新顶点,重复此步骤直至刚访问过的顶点没有未被访问过的邻接点为止 → 返回前一个访问过且仍有未被访问的邻接点的顶点,找出该顶点的下一个未被访问的邻接点,访问该顶点
(2)BFS
从图中某个顶点v出发,访问v → 依次访问v的各个未曾访问过的邻接点 → 分别从这些邻接点出发依次访问它们的邻接点,并使“先被访问的顶点的邻接点”先于“后被访问的顶点的邻接点”被访问,重复此步骤,直至图中所有已被访问的顶点的邻接点已被访问
第六章作业
给定一个有N个顶点和E条边的无向图,请用DFS和BFS分别列出其所有的连通集。假设顶点从0到N−1编号。进行搜索时,假设我们总是从编号最小的顶点出发,按编号递增的顺序访问邻接点。
输入格式:
输入第1行给出2个整数N(0<N≤10)和E,分别是图的顶点数和边数。随后E行,每行给出一条边的两个端点。每行中的数字之间用1空格分隔。
输出格式:
按照"{ v1 v2 ... vk }"的格式,每行输出一个连通集。先输出DFS的结果,再输出BFS的结果。
输入样例:
8 6
0 7
0 1
2 0
4 1
2 4
3 5
输出样例:
{ 0 1 4 2 7 }
{ 3 5 }
{ 6 }
{ 0 1 2 7 4 }
{ 3 5 }
{ 6 }
下面是对部分代码的解释
(1)定义一个图结构
typedef struct { int edge[10][10];//用来表示两顶点间是否连通的二阶矩阵 int vexnum,edgnum;//顶点数和边数 }Graph;
二维数组含义
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | |
0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 1 |
1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
2 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 0 |
3 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
4 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
5 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
6 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
7 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
1表示两顶点间存在边,0则表示两顶点间没有边
(2)深度优先函数
void DFS(Graph a,int b) //深度优先 { visited[b]=1; //令顶点对应的visited数组为1,表示该顶点已被访问过 cout<<b<<" "; //输出顶点编号及空格 for(int i=0;i<a.vexnum;i++) { if(a.edge[b][i]==1 && visited[i]==0)DFS(a,i); //若顶点对应的邻接点未被访问,则递归调用DFS函数 } }
(3)宽度优先搜索函数
void BFS(Graph a,int b) //宽度优先搜索 { visited[b]=1; //第一次入队的顶点对应的visited数组值取1,表示已被访问 int temp; //定义参数 while(!q.empty()) //若队列不为空 { temp=q.front(); //取队头元素值为temp q.pop(); //队头元素出队 cout<<temp<<" "; //输出temp值及空格 for(int i=0;i<a.vexnum;i++) { if(a.edge[temp][i]==1 && visited[i]==0) //若顶点对应的邻接点未被访问,则邻接点入队 { q.push(i); //邻接点入队 visited[i]=1; //邻接点对应的visited数组取1,表示已被访问 } } } }