DFS和BFS的思想探究

简介: DFS和BFS的思想探究

DFS(深度优先搜索 Depth First Search)


白话理解:


我觉得其实就是暴力把所有的路径都搜索出来,运用回溯,保存这次的位置,深入搜索,都搜索完了便回溯回来,搜下一个位置,直到把所有最深位置都搜一遍,要注意的一点是,搜索的时候有记录走过的位置,标记完后可能要改回来;


我的最白的理解就是,一个人每条路都一直走到黑,到头了再返回来,全走一遍,找出你想要的路。


回溯法:


回溯法是一种搜索法,按条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法;


图解:


例如这张图,从1开始到2,之后到5,5不能再走了,退回2,到6,退回2退回1,到3,一直进行;



理解这种方法比较简单,难的是要怎么用


伪代码理解:


简单来说就是这样:


void dfs()
{
  访问过的点 = 1;
  cout << " " << a;
  for (int i = 0; i < N; i++)
  {
    if (其他点到这个点有边并且该点未被访问过) // 该点未访问过并且其他点到这个点有边
    {
      // Dfs递归
      dfs();
    }
  }
}


详细来说:


void dfs(int deep)
{
  int x=deep/n,y=deep%n;
  // 回溯结束判断条件
  if(符合某种要求||已经不能在搜了)
  {
    做一些处理操作;
    return ;
  }
  // 判断当前回溯结点是否满足条件,或者处理数据
  // 这里可能会有多种条件,可能要循环什么的
  if(符合某种条件且有地方可以继续搜索的)
  {
    a[x][y]='x';  // 可能要改变条件,这个是瞎写的
          dfs(deep+1,sum+1);  // 搜索下一层
    a[x][y]='.';  // 可能要改回条件,有些可能不用改比如搜地图上有多少块连续的东西
  }
  // 最后可能要判断一些特殊条件,处理一些特殊数据,一般没有
}


BFS(宽度/广度优先搜索 Breadth First Search)


白话理解:


我觉得就是从某点开始,走四面可以走的路,然后在从这些路,在找可以走的路,直到最先找到符合条件的,这个运用需要用到队列(queue)。


我的最白的理解就是,一群人(无数),碰到了一个岔路,就派出去一队人继续走,遇到岔路再分,让人们一次性的遍布整个图,最后找出你想要的路。



图解:


还是这张图,从1开始搜,有2,3,4几个点,存起来,从2开始有5,6,存起来,搜3,有7,8,存起来,搜4,没有了;现在开始搜刚刚存的点,从5开始,没有,然后搜6…一直进行,直到找到;



伪代码理解:


简单来说


void bfs()
{
  创建队列
  将点压入队列;
  访问过该点 = 1;
  while (队列不为空) 
  {
    设an为队首元素;
    弹出队首元素;
    将an输出;
    for (int i = 0; i < N; i++)
    {
      if (该点未访问过并且该点与其他点有边) 
      {
        标记该点为1,被访问过
        将该点压入队列
      }
    }
  }
}


详细来说(当然,也不是每个都这样写):


int visit[N][N]// 用来记录走过的位置
int dir[4][2]={
  0,-1,
  0,1,
  -1,0,
  1,0
};  // 上下左右四个方向
struct node
{
  int x,y,bits; // 一般是点,还有步数,也可以存其他的
  ......
};
queue<node>v;
void bfs(node p)
{
  node t,tt;
  v.push(p);
  while(!v.empty())
  {
    t=v.front();// 取出最前面的
    v.pop();  // 删除
    // 终止判断
    if(找到符合条件的)
    {
      做记录;
      while(!v.empty())   // 如果后面还需要用,随手清空队列
        v.pop();  
      return;
    }
    visit[t.x][t.y]=1;  // 走过的进行标记,以免重复
    {
      tt=t;
      tt.x+=dir[i][0];
      tt.y+=dir[i][1];  // 这里的是按照:向上下左右查找的
      if(如果这个位置符合条件)
      {
        tt.bits++;    // 步数加一
        v.push(tt);   // 把它推入队列,在后面的时候就可以用了
      }
    }
  }
}


DFS和BFS的区别


image.png


总结


bfs是浪费空间节省时间,dfs是浪费时间节省空间。


  1. 数据结构:


DFS用递归的形式,用到了栈结构,先进后出。


BFS选取状态用队列的形式,先进先出。


  1. 复杂度


DFS的复杂度与BFS的复杂度大体一致(O(∣V∣2)),不同之处在于遍历的方式与对于问题的解决出发点不同,DFS适合目标明确,而BFS适合大范围的寻找。


  1. 思想


思想上来说这两种方法都是穷竭列举所有的情况。


相关文章
|
9月前
|
存储 算法
深度优先遍历(DFS):探索图的奥秘
当进行深度优先遍历(DFS)时,我们需要按照一定的步骤来遍历图中的节点。 选择起始节点:选择图中的一个起始节点作为遍历的起点。 标记已访问:将起始节点标记为已访问,并将其放入数据结构中,比如栈或递归调用。 探索相邻节点:从起始节点开始,探索与其相邻的节点。这是通过查找邻接表来实现的,邻接表存储了每个节点的相邻节点信息。 深入探索:选择一个相邻节点,标记为已访问,并将其放入数据结构中。然后,从这个相邻节点出发,继续探索其相邻节点,形成一个深入的路径。这一步是递归的核心。 回溯:当没有未访问的相邻节点时,回溯到上一个节点,继续探索其他未访问的相邻节点。这可以通过从数据结构中弹出节点来实现,或者从递
211 0
|
9月前
|
人工智能 算法 C++
【BFS】巧妙取量
【BFS】巧妙取量(c++基础算法)
44 1
|
4月前
|
机器学习/深度学习 消息中间件 算法
DFS - 常见算法题总结
DFS - 常见算法题总结
|
7月前
|
机器学习/深度学习 算法 测试技术
C++算法:深度优先搜索(BFS)的原理和实现
C++算法:深度优先搜索(BFS)的原理和实现
|
9月前
|
数据采集 算法 C++
DFS(深度优先搜索)详解(概念讲解,图片辅助,例题解释,剪枝技巧)
DFS(深度优先搜索)详解(概念讲解,图片辅助,例题解释,剪枝技巧)
112 0
|
11月前
|
机器学习/深度学习
抽象DFS:2N皇后
抽象DFS:2N皇后
|
11月前
|
存储 算法
dfs构造N叉树面试算法题
dfs构造N叉树面试算法题
78 0
|
算法 C语言
经典算法之深度优先搜索(DFS)
经典算法之深度优先搜索(DFS)
133 0
经典算法之深度优先搜索(DFS)
|
算法 前端开发
怎么理解DFS和BFS
怎么理解DFS和BFS
138 0