DFS和BFS

什么是DFS?

深度优先遍历(DFS)也叫深度优先搜索。顾名思义,深度优先,则是以深度为准则,先一条路走到底,直到达到目标。这里称之为递归下去。 DFS相当与一种工具,回溯是深度优先搜索的一种。在这里插入图片描述

简述实现步骤
1、从顶点出发。

2、访问顶点,也就是根节点。

3、依次从顶点的未被访问的邻接点出发,进行深度优先遍历;直至和顶点有路径相通的顶点被访问

4、若此时尚有顶点未被访问,则从一个未被访问的顶点出发,重新进行深度优先遍历,直到所有顶点均被访问过为止。

什么是BFS?

BFS又叫广度优先搜索,是一种利用队列实现的搜索算法。简单来说,其搜索过程和 “湖面丢进一块石头激起层层涟漪” 类似。
在这里插入图片描述
一层一层的搜索

DFS与BFS的区别

  • BFS 的重点在于队列,而 DFS 的重点在于递归。这是它们的本质区别。

  • BFS 常用于找单一的最短路线,它的特点是 “搜到就是最优解”,而 DFS 用于找所有解的问题,它的空间效率高,而且找到的不一定是最优解,必须记录并完成整个搜索,故一般情况下,深搜需要非常高效的剪枝

应用举例

acwing 1113.红与黑
在这里插入图片描述
DFS

#include<iostream>
#include<cstring> 
using namespace std;



int dx[4] = {-1,0,1,0},dy[4] = {0,1,0,-1};

const int N = 25;
char g[N][N]; //存图的
int st[N][N]; //标记这个点有没有被搜过
int n,m; //n行m列
int res;

void dfs(int x,int y)
{
    st[x][y] = 1; //标记被遍历
    for(int i=0; i<4; i++)
    {
        int a = x + dx[i], b = y + dy[i]; //邻接点的坐标
        if(a<0 || a>=n || b<0 || b>=m) continue; //出界
        if(st[a][b]) continue; //已经被访问过
        if(g[a][b] != '.') continue; //遇到障碍 
        
        res++;
        dfs(a,b);//不需要回溯
    }
}


int main()
{
    while(cin >> m >> n)
    {
        if(m==0 && n==0) break;
        res = 1;
        memset(st,0,sizeof st); 
        
        for(int i=0; i<n; i++) cin >> g[i];
    
        for(int i=0; i<n; i++)
            for(int j=0; j<m; j++)
                if(g[i][j] == '@')
                {
                    dfs(i,j); 
                    break;
                }
        cout << res << endl;        
    }
    
}

BFS

#include<iostream>
#include<queue>
#include<cstring> 
using namespace std;

typedef pair<int,int> PII;

int dx[4] = {-1,0,1,0},dy[4] = {0,1,0,-1};

const int N = 25;
char g[N][N]; //存图的
int st[N][N]; //标记这个点有没有被搜过
int n,m; //n行m列
int res;

void bfs(int x,int y)
{
    queue<PII> q; 
    q.push({x,y});
    
    while(q.size() > 0) //队列不空 
    {
        PII t = q.front(); //取出队头
        q.pop();//出队
        
        for(int i=0; i<4; i++) //遍历四个方向
        {
            int a = t.first + dx[i], b = t.second + dy[i]; //队头邻接点的坐标
            if(a<0 || a>=n || b<0 || b>=m) continue; //出界
            if(st[a][b] == 1) continue; //已经被访问过
            if(g[a][b] != '.') continue; //遇到障碍 
            
            res++;
            q.push({a,b});
            st[a][b] = 1; //标记(a,b)已经被访问过
        }
    }
}


int main()
{
    while(cin >> m >> n)
    {
        if(m==0 && n==0) break;
        res = 1;
        memset(st,0,sizeof st); 
        
        for(int i=0; i<n; i++) cin >> g[i];
    
        for(int i=0; i<n; i++)
            for(int j=0; j<m; j++)
                if(g[i][j] == '@')
                {
                    bfs(i,j);
                    break;
                }
        cout << res << endl;        
    }
    
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值