第六章小结

第六章主要学习了图的两种存储结构---邻接矩阵表示法和邻接表表示法,以及基于两种存储结构对图的遍历---深度优先遍历和广度优先遍历

PTA作业:

给定一个有N个顶点和E条边的无向图,请用DFS和BFS分别列出其所有的连通集。假设顶点从0到N−1编号。进行搜索时,假设我们总是从编号最小的顶点出发,按编号递增的顺序访问邻接点。

输入格式:

输入第1行给出2个整数N(0<N≤10)和E,分别是图的顶点数和边数。随后E行,每行给出一条边的两个端点。每行中的数字之间用1空格分隔。

输出格式:

按照"{ v​1​​ v​2​​ ... 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; 
View Code
typedef struct
{//定义邻接矩阵 
    int vexs[MNum];//顶点表 
    int arc[MNum][MNum];//邻接矩阵 
    int vexnum,arcnum;//顶点数,边数 
}Graph;
View Code定义邻接矩阵
Status create(Graph &g);
void DFS(Graph &g,int v);
void BFS(Graph &g,int v);
View Code函数声明

定义全局变量visit数组,用来判断顶点是否被访问

bool visit[MNum];
View Code数组初始化为false
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;
}
View Code主函数

主函数中先进了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;
 } 
View Code//邻接矩阵表示图
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);
       }
      }
}
View Code//DFS
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);
            }
        }
     }  
}
View Code//BFS

PTA提交作业在格式上有很大的要求;无法输出广度优先遍历的连通分量集合,就在BFS函数里加上一些输出语句,查看在程序在哪里中断,在哪运行条件不符合,可以比较有效的找到漏洞。

posted @ 2019-05-18 18:18  咖啡yuan  阅读(239)  评论(0编辑  收藏  举报