女孩和机器人一起思考

一起动脑筋 · 先看一个小故事

机器人探索树屋,先沿一个分支走到没有新路,再退回来试别的分支。

把过程摊开来看

沿着编号看一遍,再用自己的话讲一遍
  1. 起点 A先选 B
  2. 从 B继续到 D
  3. D 无新路退回 B
  4. 再探索尚未访问的分支

深度优先搜索先深入一个分支,再回退探索其他分支。

用栈或递归可记住回来的位置。图中有环时,还需要管理已访问状态。

01什么是 DFS?

DFS(Depth-First Search,深度优先搜索)的直觉是:

先沿一条路尽量走深,走不下去再回来换路

02在一棵树上怎样走?

A
BC
DEF

从 A 出发,可以先进入 B,再继续深入 B 的子节点,完成后再回到 A 去处理 C。

03递归 DFS 怎样写?

void dfs(int u) {
    visited[u] = true;

    for (int v : graph[u]) {
        if (!visited[v]) {
            dfs(v);
        }
    }
}

每次进入一个节点,就继续递归访问一个尚未访问的邻居。

04DFS 一定要用递归吗?

不一定。也可以显式使用栈:

std::stack<int> st;
st.push(start);

递归 DFS 使用的是函数调用栈;迭代 DFS 则自己维护一个栈结构。

05为什么图里通常要 visited?

因为图可能有环。如果 A-B-C-A 构成环,不记录访问状态就可能不停绕圈。

06DFS 能做什么?

  • 遍历图或树
  • 判断可达性
  • 寻找连通分量
  • 回溯搜索
  • 拓扑、桥、割点等更高级图算法的基础

你已经知道了什么

  • DFS 会沿一条路径尽量深入。
  • 走不下去后再退回上一层。
  • DFS 可以递归实现,也可以用栈实现。
  • 图中常需要 visited 防止重复访问。
  • DFS 是很多图和回溯算法的基础。

下一篇:DFS 和递归有什么关系?

轮到你来试一试

在一条路尽头没找到目标,应该马上说不存在吗?

想好了吗?点开看解释

不能,应回退到还有未探索分支的位置继续搜索。