Go中DFS易panic因未校验map键存在性,访问graph6前须用_,ok:=graph[node]检查;邻接表需预排序或逆序入栈以满足字典序;路径收集须传值避免切片共享。

Go 语言里写 DFS 不需要自己造栈或递归框架——用好 map[int][]int 和 visited 就能覆盖绝大多数图遍历需求,但边界条件和递归退出逻辑最容易出错。
DFS 递归实现为什么常 panic: runtime error: index out of range?
这不是 Go 特有,而是邻接表访问时没校验节点是否存在。比如图中只有节点 1–5,但代码里直接访问 graph[6],而 graph 是 map[int][]int,对未定义 key 返回空切片;但如果后续又去取 graph[6][0],就会 panic。
- 务必在访问前检查
_, ok := graph[node],尤其在输入边不保证节点连续时(如题目给的是稀疏编号 1、3、7、12) - 不要依赖
len(graph)判断节点总数——map 长度是已插入键的数量,不是最大节点编号 - 若需按编号范围遍历(如“节点编号 1 到 n”),应单独维护
n或用map[int]bool记录所有出现过的节点
用栈模拟 DFS 时,stack = append(stack, neighbor) 的顺序影响路径结果
邻接节点入栈顺序决定了 DFS 的“优先级”。比如从节点 1 出发,邻接点是 [3, 2],若按原序入栈:stack = append(stack, 3); stack = append(stack, 2),则栈顶是 2,下一次 pop 就先访问 2——这等价于“右子树优先”。如果题目要求字典序最小路径(如输出所有 1→n 路径时按节点编号升序),必须先对 graph[node] 排序再逆序入栈(或正序入栈后从尾部 pop)。
- 升序路径需求:对
graph[node]调用sort.Ints(),再倒序遍历并append - 避免反复排序:建图时就对每个节点的邻接列表预排序(适合静态图)
- 注意:递归版 DFS 无法控制这一顺序,除非显式排序
graph[node]后再 range
找所有路径(如 1 → n)时,path 必须传值或深拷贝
Go 中切片是引用类型。若用全局 path []int 并在递归中 append(path, node),回溯时修改会污染上层调用栈里的 path。常见错误是只看到一条路径被重复输出多次。
立即学习“go语言免费学习笔记(深入)”;
- 安全做法:每次递归传
append(path, node)的结果(新切片),不复用原变量 - 性能敏感场景可预分配容量:
newPath := make([]int, len(path)+1); copy(newPath, path); newPath[len(path)] = node - 切忌在回溯前
path = path[:len(path)-1]—— 这会改原始底层数组,影响其他分支
真正卡住人的往往不是算法逻辑,而是图结构初始化时漏边、节点编号越界、或路径收集时切片误共享。写完先用 3 个节点的最简图(1→2→3)跑通,再加复杂度。


















