generator 用 yield 递归委托天然适配树的 dfs 迭代,无需手动维护栈,语义清晰且可中断恢复;通过调整 yield 与 yield 顺序可灵活实现前/中/后序遍历,并支持防环、图遍历及异步扩展。

Generator 可以用 yield* 递归委托和 yield 逐层暴露节点,天然适配树的 DFS 迭代逻辑——不用手动维护栈,代码清晰且可中断、可恢复。
用 yield* 委托子树遍历
每个节点的 Generator 可直接 yield 自身,再用 yield* 委托子节点的 Generator,形成递归展开。引擎自动处理调用栈,避免显式 push/pop。
例如:
function* dfs(node) {
if (!node) return;
yield node; // 访问当前节点
for (const child of node.children) {
yield* dfs(child); // 委托给子树,等价于展开其所有 yield
}
}这样写语义直观:DFS 就是“访问自己 + 深度遍历每个孩子”,yield* 完美对应“展开子过程”的意图。
支持前/中/后序,只需调整 yield 位置
顺序由 yield 和 yield* 的相对位置决定,无需改结构:
- 前序:yield 当前 → yield* 子树
- 中序(仅二叉树常见):yield* 左 → yield 当前 → yield* 右
- 后序:yield* 子树 → yield 当前
比如后序遍历:
function* postOrder(node) {
if (!node) return;
for (const child of node.children) {
yield* postOrder(child);
}
yield node; // 所有子树遍历完才产出自己
}配合 for...of 实现惰性、可中断的遍历
Generator 返回迭代器,遍历过程按需执行,适合大数据量或需提前退出的场景:
- 用
for (const node of dfs(root)) { ... }简洁消费 - 中途调用
iterator.return()可释放资源、触发清理逻辑 - 结合
next(value)可实现“遍历中注入控制信号”,比如跳过某子树
例如带条件中断:
const it = dfs(root);
let result;
while (!(result = it.next()).done) {
if (result.value.id === 'target') break;
process(result.value);
}处理非标准树结构(如图、带环、异步子节点)
Generator 的灵活性可自然延展:
-
防环:传入
visited = new Set()作为参数,每次 yield 前检查 -
图遍历:把
children替换为neighbors,逻辑不变 -
异步 DFS:用
async function*,配合await yield*(注意需用for await...of消费)
示例(带环检测):
function* dfsSafe(node, visited = new Set()) {
if (!node || visited.has(node)) return;
visited.add(node);
yield node;
for (const child of node.children) {
yield* dfsSafe(child, visited);
}
}Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











