深度优先搜索DFS

今天我们用简单易懂的语言来讲讲深度优先搜索DFS喵!
用一句话来说DFS就是“一条路走到黑,不撞南墙不回头!”。

1. 首先,不用害怕它,可以把它想象成勇士探路的故事

一个勇士,独自进入了一个迷宫寻找宝藏。他有两样东西:
一支笔:用来在走过的路上画个叉,防止自己原地绕圈子喵。
一根很长的红线:一头绑在迷宫入口,一头绑在身上,随时可以顺着红线退回去喵。
他是这样探险的:

  • 第一步(深入):站在一个十字路口,挑了一条路,只要有路,就一直往前冲! :raised_fist:
  • 第二步(碰壁):走着走着,呀 :sweat_smile:,前面是死路(或这条路你用笔画叉了)。
  • 第三步(回溯):没路了,咋办 :face_with_monocle:?顺着红线,往后退一步,退到上一个十字路口。
  • 第四步(换路):回到上一个十字路口,看还有没有没走过路。如果有,就换条路继续走到黑;如果所有的路都是死路,那就再往后退一步。

就这样,不断往前冲 ➔ 碰壁 ➔ 退回 ➔ 换条路再冲,直到找到宝藏为止。这个过程,在c++里就叫 DFS深度优先搜索

2. 当然DFS 也有优缺点喵

  • 优点(省内存):因为只有一人在走,只需要记住走过的这条“红线”就行了,所以它很省电脑内存,代码写起来也更短(虽然作者感觉也没那么短 :sweat_smile:)。
  • 缺点(容易绕远路):因为是随便挑路走到黑,很可能宝藏就在左边,却选了右边,绕了迷宫几圈才找到。所以,DFS 找到的第一条路,通常不是最短的路

那它C++ 代码长什么样?
DFS 在 C++ 里通常不需要复杂的名单,而是用“递归”(函数自己调用自己)。
给大家看一个极简的代码骨架:

 //这个函数的意思是:勇士来到当前位置开始探险
void dfs(当前坐标x, 当前坐标y) {
 //到达终点啦!停止!
if (当前坐标 == 宝藏坐标) {
    放烟花庆祝();
    return; // 探险结束
}

//拿出笔画个叉,表示这里我来过了!
标记这个位置走过了;

//开始“不撞南墙不回头”的试探!
if (前面的路能走) {
    dfs(前面的一步); // 勇士往前迈一步,继续探险
}
if (后面的路能走) {
    dfs(后面的一步); 
}
if (左边的路能走) {
    dfs(左边的一步); 
}
if (右边的路能走) {
    dfs(右边的一步); 
}//这里也可以用for循环简化写哦

//可选操作:如果四周都走不通,我要退回去了,有时候需要把地上的笔印擦掉(回溯)
}

最后小结:
DFS深度优先就是:单人勇士拿红线探险,碰壁就退一步换路喵(常用在走迷宫、拼图游戏)。

1 个赞

多谢大佬总结!

thank you

递归?