当前位置: 首页 > news >正文

algorithm: DFS 示例及pseduocode及visited 5/999

🔹 图 (Graph)

0 -- 1 -- 2
|    |
3 -- 4
  • 节点:0,1,2,3,4
  • 0 开始做 DFS(递归方式)

🔹 DFS 步骤

DFS(0) → DFS(1) → DFS(2) → 回溯 → DFS(4) → DFS(3)


🔹 表格演示 DFS 执行过程

步骤当前节点动作已访问 (visited)栈/递归路径
10访问 0{0}[0]
20 → 1访问 1{0,1}[0,1]
31 → 2访问 2{0,1,2}[0,1,2]
42无新邻居 → 回溯{0,1,2}[0,1]
51 → 4访问 4{0,1,2,4}[0,1,4]
64 → 3访问 3{0,1,2,4,3}[0,1,4,3]
73无新邻居 → 回溯{0,1,2,4,3}[0,1,4]
84无新邻居 → 回溯{0,1,2,4,3}[0,1]
91所有邻居访问完 → 回溯{0,1,2,4,3}[0]
100所有邻居访问完 → 结束{0,1,2,4,3}[]

🔹 最终 DFS 遍历顺序

0 → 1 → 2 → 4 → 3

这样你就可以清楚看到:DFS 是“走到最深,再回溯”。
表格中的 栈/递归路径 就是 DFS 的精髓。

Perfect 👍 Let’s do DFS (Depth-First Search) pseudocode.
I’ll give you both the recursive and iterative (stack-based) versions, since both are common.


🔹 Recursive DFS Pseudocode

DFS(Graph, node, visited):if node is already in visited:returnmark node as visitedprocess(node)   // e.g., print it, check if targetfor each neighbor in Graph[node]:DFS(Graph, neighbor, visited)

🔹 Iterative DFS (using stack)

DFS(Graph, start):create a stack Screate a set visitedpush start onto Swhile S is not empty:node ← pop from Sif node not in visited:mark node as visitedprocess(node)  // e.g., print it, check targetfor each neighbor in Graph[node]:if neighbor not in visited:push neighbor onto S

🔹 Key Differences from BFS

BFSDFS
Uses a queue (FIFO)Uses a stack (LIFO) or recursion
Explores level by levelExplores deep into one branch before backtracking
Guarantees shortest path in unweighted graphDoes not guarantee shortest path, but good for exploring all possibilities

🔹 Example Walkthrough (Graph)

Graph:

0 -- 1 -- 2
|    |
3 -- 4
  • Start = 0
  • DFS order (recursive): 0 → 1 → 2 → 4 → 3
  • BFS order (for comparison): 0 → 1 → 3 → 2 → 4

Summary

  • DFS can be written naturally with recursion.
  • Or simulate recursion with a stack.
  • Core idea = “go as deep as possible, then backtrack.”

🔹 为什么 DFS 需要 visited 标记?

  1. 避免死循环

    • 图(Graph)可能有环,比如:

      A -- B\  /C
      
    • 如果没有 visited,DFS(A) 会去 B → 再回 A → 再去 B → … 无限循环。

    • visited 用来阻止这种情况:节点一旦访问过,就不再重复进入。

  2. 保证每个节点只处理一次

    • DFS 的目标通常是“遍历所有节点”。
    • 如果没有 visited,你可能会多次访问同一个节点,效率变成 指数级,甚至永远不结束。
  3. 区分路径探索和回溯

    • 在回溯类题目(如数独、八皇后)中,visited 不光避免死循环,还用来“标记当前路径上使用的节点”。
    • 回溯时需要“撤销”这个标记,保证别的分支还能用这个节点。

🔹 举例说明

假设图:

0 -- 1 -- 2
|         |
3 --------4

如果没有 visited

  • 0 出发 → 到 1 → 再到 2 → 再到 4 → 回到 3 → 再到 0 → 又开始循环。
  • DFS 进程就死锁在环里了。

如果有 visited

  • 第一次访问 0 时,标记 0
  • 下次遇到 0 时直接跳过,不再深入。
  • 遍历顺利完成。

🔹 DFS 和 BFS 都需要 visited 吗?

  • :需要(因为可能有环)。

  • :不需要(树无环,父节点不会被回溯成子节点)。

    • 所以很多二叉树题目里,你没见过 visited

结论
DFS 需要 visited,是为了:

  1. 防止在有环的图里无限循环;
  2. 保证每个节点只访问一次,避免重复工作;
  3. 在回溯问题中,用来限制路径和恢复状态。

明白了,你问的是这一行:

DFS(neighbor, visited)

🔹 为什么要这一步?

  1. 核心目的:递归探索邻居节点

    • DFS(深度优先搜索)的思想是“走到最深再回头”。
    • 当我们访问一个节点 node 后,必须去访问它所有未访问的邻居。
    • DFS(neighbor, visited) 就是执行这一步:进入邻居节点的深度搜索。
  2. 保证完整遍历

    • 如果不调用 DFS 遍历邻居,就只能访问当前节点,无法访问整张图或整棵树。
    • 递归调用可以不断深入,直到访问完最深的分支,再回溯到上层。
  3. 实现回溯

    • 每一次递归调用相当于走入一个新的分支。
    • 当这一分支访问完毕,函数自动返回上层调用 → 回到原来的节点继续访问其他邻居。
    • 这就是“回溯”的关键机制。
  4. 结合 visited 防止重复

    • 在递归前检查 neighbor not in visited,防止环路导致无限递归。
    • 所以每一次递归都是安全的,只会访问尚未访问的节点。

🔹 用一句话总结

这一行的作用就是 深入探索当前节点的每一个邻居,确保整个图/树被完整遍历,同时利用递归实现回溯


表格 来展示 DFS 中递归调用 DFS(neighbor, visited) 的作用,以及它如何实现深入探索与回溯

假设图如下:

0 -- 1 -- 2
|    |
3 -- 4

从节点 0 开始 DFS。


表格说明 DFS 递归执行过程

步骤当前函数调用 (节点)动作visited输出顺序递归栈
1DFS(0)访问 0{0}[0][0]
2DFS(0) → DFS(1)访问 1{0,1}[0,1][0,1]
3DFS(1) → DFS(2)访问 2{0,1,2}[0,1,2][0,1,2]
4DFS(2) → 无邻居可访问回溯{0,1,2}[0,1,2][0,1]
5DFS(1) → DFS(4)访问 4{0,1,2,4}[0,1,2,4][0,1,4]
6DFS(4) → DFS(3)访问 3{0,1,2,3,4}[0,1,2,4,3][0,1,4,3]
7DFS(3) → 无邻居可访问回溯{0,1,2,3,4}[0,1,2,4,3][0,1,4]
8DFS(4) → 所有邻居访问完回溯{0,1,2,3,4}[0,1,2,4,3][0,1]
9DFS(1) → 所有邻居访问完回溯{0,1,2,3,4}[0,1,2,4,3][0]
10DFS(0) → DFS(3)已访问 → 跳过{0,1,2,3,4}[0,1,2,4,3][0]
11DFS(0) → 所有邻居访问完结束{0,1,2,3,4}[0,1,2,4,3][]

🔹 说明

  1. 当前函数调用 (节点)

    • 显示每次递归进入哪个节点。
  2. 动作

    • “访问”表示处理节点(打印/保存);
    • “回溯”表示递归返回上一层,继续访问其他邻居。
  3. visited

    • 标记哪些节点已经访问过,避免重复访问或死循环。
  4. 输出顺序

    • 记录遍历节点顺序。
  5. 递归栈

    • 显示当前 DFS 调用栈(最右边是栈顶)。
    • 当一个分支访问完成,栈会弹出 → 实现回溯。

结论

  • 每一次 DFS(neighbor, visited) 都是“走向下一层分支”。
  • 当分支访问完毕,函数返回 → 栈弹出 → 自动回到上层节点 → 访问下一个邻居。
  • 这就是 DFS 的 递归 + 回溯机制 在表格中的直观体现。
http://www.dtcms.com/a/430933.html

相关文章:

  • 机器学习——聚类kmeans算法详解
  • 在Ubuntu如何安装Python3.9(Ubuntu 20.04)
  • Linux任务切换统计和局部描述符表设置以及加载函数的实现
  • ICT 数字测试原理 3 --SAFETYGUARD 文件
  • 网站改版用新空间好吗北京市保障房建设投资中心网站首页
  • 中职计算机网站建设教学计划医院网站建设策划书
  • [NOIP 2015 提高组] 神奇的幻方 Java
  • 基于单片机的黑板粉尘检测清除装置(论文+源码)
  • GameObject 常见类型详解 -- 陷阱(TRAP)
  • 日语学习-日语知识点小记-进阶-JLPT-N1阶段应用练习(2):语法 +考え方15+2022年7月N1
  • Windows 系统监控工具:项目架构与实现详解
  • 丹阳企业网站建设如何安装wordpress的备份
  • RAG核心特性:ETL
  • 手机网站显示建设中怎么看公司网站是哪里做的
  • GameObject 常见类型详解 -- 傻瓜(GOOBER)
  • 【Ubuntu 20.04升级python3.9后终端打不开的bug】
  • ttkbootstrap Tableview 右键编辑中文支持解决方案
  • 【数据结构与算法学习笔记】双指针
  • 模仿建设银行网站asp网站开发工具神器
  • C#基础06-函数异常
  • PostgreSQL LIMIT 语句详解
  • 网站开发是什么部门wordpress 缩略图清理
  • Kubernetes网络策略实战:精准控制frontend与backend跨-tail通信
  • 关于制作网站收费标准网站的结构类型
  • 【word解析】从OLE到OMML:公式格式转换的挑战与解决方案
  • 云梦网站开发如何做好企业网站
  • 常德网站制作公司多少钱服务器出租
  • Python 2025:低代码开发与自动化编程新纪元
  • wordpress手机端网站模板建站程序下载
  • SQL 多表查询常用语法速查:INNER JOIN / LEFT JOIN / RIGHT JOIN