- 任务要求
- 参考答案
- 评论2
- 任务描述
- 相关知识
- 编程要求
- 测试说明
任务描述
本关任务:以邻接矩阵存储图,要求编写程序实现图的广度优先遍历。
相关知识
广度优先遍历类似于树的按层次遍历的过程。
假设从图中某顶点v
出发,在访问了v
之后依次访问v
的各个未曾访问过和邻接点,然后分别从这些邻接点出发依次访问它们的邻接点,并使“先被访问的顶点的邻接点”先于“后被访问的顶点的邻接点”被访问,直至图中所有已被访问的顶点的邻接点都被访问到。
若此时图中尚有顶点未被访问,则另选图中一个未曾被访问的顶点作起始点,重复上述过程,直至图中所有顶点都被访问到为止。
换句话说,广度优先遍历图的过程中以v
为起始点,由近至远,依次访问和v
有路径相通且路径长度为1,2,…的顶点。
本关卡提供顺序队列sqqueue
的相关操作和功能,顺序队列数据类型定义及相关操作函数接口定义如下,在进行图的广度优先遍历的过程中,可以根据需要调用以下操作:
struct SqQueue
{
QElemType *base; // 初始化的动态分配存储空间
int front; // 头指针,若队列不空,指向队列头元素
int rear; // 尾指针,若队列不空,指向队列尾元素的下一个位置
};
void InitQueue(SqQueue &Q); // 构造一个空循环队列Q
void DestroyQueue(SqQueue &Q); // 销毁循环队列Q,Q不再存在
void ClearQueue(SqQueue &Q); // 将Q清为空循环队列
int QueueEmpty(SqQueue Q); // 若循环队列Q为空队列,则返回TRUE;否则返回FALSE
int QueueLength(SqQueue Q); // 返回Q的元素个数,即循环队列的长度
int GetHead(SqQueue Q,QElemType &e); // 若循环队列不空,则用e返回Q的队头元素,并返回OK;否则返回ERROR
int EnQueue(SqQueue &Q,QElemType e); // 插入元素e为循环队列Q的新的队尾元素
int DeQueue(SqQueue &Q,QElemType &e); // 若循环队列不空,则删除Q的队头元素,用e返回其值,并返回OK;否则返回ERROR
void QueueTraverse(SqQueue Q,void(*vi)(QElemType)); // 从队头到队尾依次对队列Q中每个元素调用函数vi()
编程要求
根据提示,在右侧编辑器补充代码,实现以邻接矩阵作为存储结构的图广度优先遍历算法:
- void BFSTraverse(MGraph G); // 图G存在,从第1个顶点起,按广度优先非递归遍历图G,并对每个顶点调用函数visit一次且仅一次
测试说明
平台会对你编写的代码进行测试:
测试输入: 0
lt2.txt
输入说明: 第一行输入
0
,表示输入图的类型为有向图。 第二行输入文件名,该文件里保存了图的数据信息,内容如下:
第1行为图的顶点的个数n; 第2行为图的边的条数m; 第3行至第n+2行是n个顶点的数据; 第n+3行至第n+m+2行是m条边的数据;
预期输出: 有向图
7个顶点9条边。顶点依次是: 高等数学 程序设计基础 C语言 离散数学 数据结构 编译原理 操作系统
图的邻接矩阵:
0 0 1 1 0 0 0
0 0 1 0 1 0 0
0 0 0 0 1 0 0
0 0 0 0 1 1 0
0 0 0 0 0 1 1
0 0 0 0 0 0 0
0 0 0 0 0 0 0
广度优先遍历序列:
高等数学 C语言 离散数学 数据结构 编译原理 操作系统 程序设计基础
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<limits.h>
#include"MGraph.h"
#include"sqqueue.h"
void BFSTraverse(MGraph G);// 图G存在,从第1个顶点起,按广度优先非递归遍历图G,并对每个顶点调用函数visit一次且仅一次
int visited[MAX_VERTEX_NUM]; // 访问标志数组(全局量)
int main()
{
MGraph g;
VertexType v1,v2;
CreateGraphF(g); // 利用数据文件创建图
Display(g); // 输出图
printf("广度优先遍历序列:\n");
BFSTraverse(g);
return 0;
}
void BFSTraverse(MGraph G)
{ // 图G存在,从第1个顶点起,按广度优先非递归遍历图G,并对每个顶点调用函数visit一次且仅一次
/********** Begin **********/
int v,u,w;
SqQueue Q;
for(v=0;v<G.vexnum;v++)
visited[v]=0;
InitQueue(Q);
for(v=0;v<G.vexnum;v++)
if(!visited[v]){
visited[v]=1;
visit(G.vexs[v]);
EnQueue(Q,v);
while(!QueueEmpty(Q)){
DeQueue(Q,u);
for(w=FirstAdjVex(G,G.vexs[u]);w>=0;w=NextAdjVex(G,G.vexs[u],G.vexs[w]))
if(!visited[w]){
visited[w]=1;
visit(G.vexs[w]);
EnQueue(Q,w);
}
}
}
printf("\n");
/********** End **********/
}
输出说明: 第一行输出图的类型。 第二行起输出图的顶点和边的数据信息。 最后一行为从“高等数学”出发进行广度优先遍历的序列。