第六章主要学习了图的两种存储结构---邻接矩阵表示法和邻接表表示法,以及基于两种存储结构对图的遍历---深度优先遍历和广度优先遍历
PTA作业:
给定一个有N个顶点和E条边的无向图,请用DFS和BFS分别列出其所有的连通集。假设顶点从0到N−1编号。进行搜索时,假设我们总是从编号最小的顶点出发,按编号递增的顺序访问邻接点。
输入格式:
输入第1行给出2个整数N(0<N≤10)和E,分别是图的顶点数和边数。随后E行,每行给出一条边的两个端点。每行中的数字之间用1空格分隔。
输出格式:
按照"{ v1 v2 ... vk }"的格式,每行输出一个连通集。先输出DFS的结果,再输出BFS的结果。
sample
输入
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 }
采用邻接矩阵存储结构解决这个问题
#include <iostream> #include <queue>//队列 using namespace std; #define MNum 10 #define OK 1 typedef int Status;
typedef struct {//定义邻接矩阵 int vexs[MNum];//顶点表 int arc[MNum][MNum];//邻接矩阵 int vexnum,arcnum;//顶点数,边数 }Graph;
Status create(Graph &g); void DFS(Graph &g,int v); void BFS(Graph &g,int v);
定义全局变量visit数组,用来判断顶点是否被访问
bool visit[MNum];
int main() { Graph g; create(g); for(int i=0;i<g.vexnum;i++) { if(!visit[i]) { visit[i]=true; cout<<"{"<<" "; DFS(g,i); cout<<"}"<<endl; } } //将visit数组重新置为false for(int i=0;i<g.vexnum;++i) visit[i]={false}; for(int i=0;i<g.vexnum;i++) { //若顶点未访问,先visit数组置true,递归BFS if(!visit[i]) { visit[i]=true; cout<<"{"<<" "; BFS(g,i); cout<<"}"<<endl; } } return 0; }
主函数中先进了DFS,visit数组已经全部置为true,所以在进行BFS时须再次将visit数组置为false,这样BFS才能继续进行,否则不会输出广度优先遍历下图的连通分量集合(我就是在这入坑了)。
Status create(Graph &g) { int v1,v2; int n,i,j,k; cin>>g.vexnum>>g.arcnum;//输入顶点数,边数 for(n=0;i<g.vexnum;++i) g.vexs[i]=i;//顶点即数组下标 for(i=0;i<g.vexnum;++i) for(j=0;j<g.vexnum;++j) g.arc[i][j]=0;//初始化邻接矩阵为0 for(k=0;k<g.arcnum;++k) {//两顶点有边即以两顶点为下标的元素置1 cin>>v1>>v2;//输入顶点下标 g.arc[v1][v2]=1; g.arc[v2][v1]=g.arc[v1][v2];//无向图的对称性 } return OK; }
void DFS(Graph &g,int v) {//从v顶点开始的深度优先遍历 cout<<v<<" "; for(int w=0;w<g.vexnum;++w) { if((g.arc[v][w]!=0)&&(!visit[w])) {//如果边存在,顶点未访问,递归调用DFS visit[w]=true; DFS(g,w); } } }
void BFS(Graph &g,int v) {//从顶点v开始广度优先遍历 queue <int> q; int u; q.push(v);//初始顶点入栈 while(!q.empty()) { u=q.front(); cout<<u<<" ";//输出对头 q.pop(); for(int i=0;i<g.vexnum;i++) {//两顶点边存在且顶点未被访问,该顶点对于应的visit数组置true,将顶点入队 if((g.arc[u][i]!=0)&&(!visit[i])) { visit[i]=true; q.push(i); } } } }
PTA提交作业在格式上有很大的要求;无法输出广度优先遍历的连通分量集合,就在BFS函数里加上一些输出语句,查看在程序在哪里中断,在哪运行条件不符合,可以比较有效的找到漏洞。