react树形结构如何遍历
深度优先遍历(DFS)
深度优先遍历从根节点开始,沿着树的深度遍历子节点,直到没有子节点为止,再回溯到上一级节点。递归实现是最常见的方式。
function traverseTreeDFS(node) {
if (!node) return;
console.log(node.value); // 处理当前节点
node.children?.forEach(child => traverseTreeDFS(child)); // 递归子节点
}
广度优先遍历(BFS)
广度优先遍历按层级顺序遍历,使用队列辅助实现。从根节点开始,依次处理每一层的所有节点。
function traverseTreeBFS(root) {
const queue = [root];
while (queue.length > 0) {
const node = queue.shift();
console.log(node.value); // 处理当前节点
node.children?.forEach(child => queue.push(child)); // 子节点入队
}
}
前序遍历
前序遍历在访问子节点前先处理当前节点,适合需要优先处理父节点的场景(如复制树结构)。

function preOrderTraversal(node) {
if (!node) return;
console.log(node.value); // 先处理当前节点
node.children?.forEach(child => preOrderTraversal(child));
}
后序遍历
后序遍历先访问所有子节点,最后处理当前节点,适合依赖子节点结果的场景(如计算子树大小)。
function postOrderTraversal(node) {
if (!node) return;
node.children?.forEach(child => postOrderTraversal(child));
console.log(node.value); // 最后处理当前节点
}
非递归实现(使用栈)
对于深度优先遍历,可以用显式栈替代递归调用,避免调用栈过深的问题。

function dfsWithStack(root) {
const stack = [root];
while (stack.length > 0) {
const node = stack.pop();
console.log(node.value);
// 子节点逆序入栈,保证处理顺序正确
node.children?.slice().reverse().forEach(child => stack.push(child));
}
}
使用生成器实现遍历
通过生成器函数可以按需产生节点,适合大规模树的惰性遍历。
function* traverseGenerator(node) {
yield node.value;
for (const child of node.children || []) {
yield* traverseGenerator(child);
}
}
// 使用示例
for (const value of traverseGenerator(root)) {
console.log(value);
}
带层级的遍历
在广度优先遍历基础上记录层级信息,适用于需要分层处理的场景。
function levelOrderTraversal(root) {
const queue = [{ node: root, level: 0 }];
while (queue.length > 0) {
const { node, level } = queue.shift();
console.log(`Level ${level}:`, node.value);
node.children?.forEach(child =>
queue.push({ node: child, level: level + 1 })
);
}
}
遍历时修改树结构
若需在遍历时修改树结构(如过滤节点),建议先复制节点或使用后序遍历。
function filterTree(node, predicate) {
if (!node) return null;
const filteredChildren = node.children
?.map(child => filterTree(child, predicate))
.filter(Boolean);
return predicate(node)
? { ...node, children: filteredChildren }
: null;
}






