DFS伪代码

是的,DFS 也有非常标准、经典的伪代码结构,和 BFS 一样清晰规范。虽然你提供的图片是 BFS 的模板,但 DFS 同样有“教科书级”的写法 —— 尤其是用于图遍历或状态空间搜索时。

✅ DFS 标准伪代码(递归版)

这是最常用、最直观的 DFS 形式:

DFS(u):
vis[u] = true // 标记当前节点已访问
for each neighbor v of u:
if not vis[v]:
DFS(v) // 递归深入

如果是带目标判断或路径记录的版本(如你的排列问题),会扩展为:

DFS(now, last):
if now == n: // 终止条件:达到目标深度/长度
output solution
return

for i from 1 to n: // 枚举所有可能的下一步
if valid(i, last) and not vis[i]: // 合法性 + 未访问
vis[i] = true
ans[now] = i
DFS(now + 1, i & 1) // 递归进入下一层
vis[i] = false // 回溯!关键步骤

💡 注意:回溯(backtrack) 是 DFS 在组合/排列/子集等问题中的核心特征,而纯图遍历 DFS 通常不需要回溯(因为只关心是否访问过)。

🔄 DFS 非递归版(显式栈实现)

如果你想要一个和 BFS “对称”的非递归版本(用栈代替队列),也可以这样写:

DFS(S):
stack st
st.push(S)
vis[S] = true

while st not empty:
now = st.top()
st.pop()

if now == T: return Type // 可选:找到目标就返回

for each next_status from now:
if valid(next_status) and not vis[next_status]:
vis[next_status] = true
st.push(next_status)

⚠️ 注意:这个非递归版本 不保证和递归版完全相同的遍历顺序(因为栈是 LIFO,且弹出时机不同),但它确实是 DFS 的一种实现方式。

🆚 对比 BFS 和 DFS 伪代码结构
特性 BFS DFS(递归)
数据结构 队列 queue 系统调用栈(隐式)或 stack(显式)

遍历顺序 层序(广度优先) 深度优先(一条路走到底)

是否需要回溯 否 是(在组合问题中)

终止条件 找到目标即返回 到达叶子/满长度/无合法分支

标记时机 入队前标记 进入函数时标记

撤销标记 不需要 需要(回溯时 vis[i]=false)

📌 总结

✅ DFS 绝对有标准伪代码结构,而且比 BFS 更灵活:

递归版简洁优雅,适合大多数场景;
非递归版可用栈模拟,适合避免递归爆炸或需要控制流程时;
在组合优化问题中,DFS 常与“回溯”结合,形成 Backtracking Algorithm,其伪代码包含“选择 → 递归 → 撤销”三要素。

你之前看到的 DFS 代码(排列生成)正是这种“回溯型 DFS”的经典范例!

📌 如果你想把 DFS 写成和 BFS 一样“结构化”的模板,可以参考下面这个通用框架:

function DFS(state):
if is_goal(state):
record_solution()
return

for next_state in generate_next_states(state):
if is_valid(next_state) and not visited[next_state]:
mark_visited(next_state)
DFS(next_state)
unmark_visited(next_state) // 回溯

这和 BFS 的 while(queue) + for(neighbors) 结构高度对称,只是把“队列”换成了“递归调用”,并多了“回溯”一步。

希望这能帮你建立完整的 DFS/BFS 对比认知!

posted @ 2026-03-03 00:58  peter_shen  阅读(46)  评论(0)    收藏  举报