算法设计与分析作业四DFS&BFS

这篇博客介绍了如何使用C++实现无向无权图的广度优先搜索(BFS)和深度优先搜索(DFS)方法,通过邻接矩阵来存储图的数据结构,并给出了具体的代码实现。博客还提供了输入输出示例,帮助理解算法的工作原理。

1. 

【问题描述】

在无向无权图的邻接矩阵中,有N个顶点和M条边。从1号顶点开始,按“广度优先遍历”方式遍历全部顶点。

输入形式】
第1行输入整数N和M,用“空格”分开;表示N个顶点和M条边。

接下来M行,每行输入1对整数V和W,用“空格”分开;表示顶点V和W之间有1条边。

【输出形式】
输出M行,每行1个整数V;表示从1号顶点开始,按“广度优先遍历”方式遍历各个顶点的次序。

【样例输入】

4 4

1 2

1 3

4 2

4 3

/*  (无向无权图)邻接矩阵  BFS  */
/*
关于广度优先图解看此博客,感觉讲得还可以
https://blog.csdn.net/rr123rrr/article/details/77971771
视频:https://www.bilibili.com/video/BV1Vr4y1k7Js?spm_id_from=333.999.0.0
*/
#include<bits/stdc++.h>
using  namespace  std;

const  int  size=21;
int  Map[size][size];
bool  visted[size];
/*
广度优先搜索(BFS)的过程是:
        (1)首先访问初始顶点v。
        (2)接着访问顶点v的所有未被访问过的邻接点v1,v2,…,vt。
        (3)然后再按照v1,v2,…,vt的次序,访问每一个顶点的所有未被访问过的邻接点;
                依次类推,直到图中所有和初始顶点v有路径相通的顶点都被访问过为止。
        注:利用队列“先进先出”的特点,依次记录各个顶点。  
*/
void  BFS(int  x,int  n){
        int  i;                        //  循环变量  
        int  t;                        //  中间变量(暂存)  
        queue  <int>  p;        //  队列(具有“先进先出”的特点,存放按BFS规则遍历到的各个顶点)  

        printf(  "%d\n",  x);
        visted[x]  =  true;
        p.push(x);                                //  x元素入队列  

        while(  p.size()  )  {                //  队列内还有元素  
                //***填空***
                t = p.front();  // 最早进入队列的元素
                

                //***填空***
              
                 p.pop();       //  元素出队  
                
                for(  i=1;  i<=n;  i++)        //  从1号顶点开始处理  
                        if(  !visted[i]  &&  Map[t][i]  )  { //查找t的邻接点
                                printf("%d\n",i);
                        //***填空***
                          visted[i] = true ;      

                        //***填空***
                                
                         p.push(i);        //  i元素入队列  
                        }
        }
}

int  main()
{
        int  V,E;                //  顶点的数量、边的数量  
        int  x,y;                //  顶点变量  
        int  i;                //  循环变量  

        scanf("%d  %d",&V,&E);
        memset(  visted,  false,  sizeof(visted));        //  初始化“被访问”标记  
        memset(  Map,  0,  sizeof(Map));                        //  初始化“邻接矩阵”  

        while(E--)        {
                scanf(  "%d%d",  &x,  &y  );                //  读入1条边(包含了两个节点)
        //***填空***
                
            Map[x][y]= 1 ;    //  “对称”记录两个节点的一条边(无向无权图) 
            Map[y][x]= 1 ;       // 表示x、y之间连通    
        }

        for(  i=1;  i<=V;  i++) {       //  从1号顶点开始处理  
        //***填空***
             if( !visted[i])  //如果该顶点未访问过      
                BFS(  i,  V);
        }
        return  0;
}

运行结果:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBARXZhbl9xaW5feWlfcXVhbg==,size_13,color_FFFFFF,t_70,g_se,x_16

 

2. 

在无向无权图的邻接矩阵中,有N个顶点和M条边。从1号顶点开始,按“深度优先遍历”方式遍历全部顶点。

 

【输入形式】
第1行输入整数N和M,用“空格”分开;表示N个顶点和M条边。

接下来M行,每行输入1对整数V和W,用“空格”分开;表示顶点V和W之间有1条边。

【输出形式】
输出M行,每行1个整数V;表示从1号顶点开始,按“深度优先遍历”方式遍历各个顶点的次序。

【样例输入】

4 4

1 2

1 3

4 2

4 3

/*  (无向无权图)邻接矩阵  DFS  */
//#include<bits/stdc++.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<iostream>
#include<algorithm>
using  namespace  std;
const  int  size=21;
int  Map[size][size];
bool  visted[size];
/*
深度优先搜索(DFS)的过程是:
        (1)从图中某个初始顶点v出发,首先访问初始顶点v。
        (2)然后选择一个与顶点v相邻且没被访问过的顶点w为初始顶点,再从w出发进行深度优先搜索。
        (3)重复直到图中与当前顶点v邻接的所有顶点都被访问过为止。
        显然,这个搜索过程是个递归过程。
*/
void  DFS(int  x,int  n){
        int  i;        //  循环变量  

        printf("%d\n",x);
        //***填空***
        
         visted[x]=true ;


        for(  i=1;  i<=n;  i++)        //  从1号顶点开始处理  
        //***填空***
        if( !visted[i] && Map[x][i] )        
           DFS(i,n);
}

int  main()
{
      int  V;                //  顶点的数量  
        int  E;                //  边的数量  
        int  i;                //  循环变量
        int  x,y;        //  顶点变量

        memset(  visted,  false,  sizeof(visted));        //  初始化“被访问”标记  
        memset(  Map,  0,  sizeof(Map));                        //  初始化“邻接矩阵”  
        scanf(  "%d  %d",  &V,  &E  );

        while(E--)        {
                scanf("%d%d",&x,&y);                        //  读入1条边(包含了两个节点)  
                Map[x][y]  =  1;
                //***填空***
        
                 Map[y][x]  =  1;  //  “对称”记录两个节点的一条边(无向无权图)  
        }

        for(  i=1;  i<=V;  i++)        //  从1号顶点开始处理  
        //***填空***
                if( !visted[i] )        
                        DFS(i,V);

        return  0;
}

运行结果:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBARXZhbl9xaW5feWlfcXVhbg==,size_14,color_FFFFFF,t_70,g_se,x_16

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值