You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在JS/TS树形结构中查找节点及其搜索路径

How to Get the Search Path When Finding a Node in a Tree

Your current stack-based search function does a great job locating the target node, but to capture the path from the root to that node, we need to adjust our approach to track the traversal path as we go. Let's cover two solid solutions: an improved stack-based implementation and a recursive approach.

Stack-Based Solution (Modified)

Instead of just storing nodes in the stack, we'll store objects that contain both the current node and the path taken to reach it. This way, when we find our target node, we already have the full path ready.

Here's the updated code:

const treeData = { id: 1, name: "Node 1", child: [{ id: 2, name: "Node 2", child: [{ id: 3, name: "Node 3" }, { id: 4, name: "Node 4", child: [{ id: 10, name: "Node 10" }] } ] }, { id: 5, name: "Node 5", child: [{ id: 6, name: "Node 6" }] } ] };

function searchTreeWithPath(nodeId, root) {
  // Each stack item is { node: currentNode, path: arrayOfNodesToHere }
  const stack = [{ node: root, path: [root] }];
  
  while (stack.length > 0) {
    const { node, path } = stack.pop();
    
    // Check if this is our target node
    if (node.id === nodeId) {
      return {
        foundNode: node,
        path: path.map(n => ({ id: n.id, name: n.name })) // Optional: return just id/name for cleaner path
      };
    }
    
    // Push children to stack (reverse to maintain order, optional)
    if (node.child) {
      // Reverse so we process children in original order (since stack is LIFO)
      [...node.child].reverse().forEach(child => {
        stack.push({
          node: child,
          path: [...path, child]
        });
      });
    }
  }
  
  // If node not found
  return { foundNode: null, path: [] };
}

// Test it
const result = searchTreeWithPath(10, treeData);
console.log("Found node:", result.foundNode);
console.log("Path to node:", result.path);

Notes:

  • We reverse the children before pushing to the stack to keep the traversal order consistent with your original function (since stacks are last-in-first-out). If order doesn't matter, you can skip the reverse.
  • The path is returned as an array of node objects (or just id/name if you use the mapped version), showing the full route from root to target.

Recursive Solution

Recursion can make path tracking feel more intuitive, as we can pass the current path along with each recursive call. If a child returns a valid path, we prepend the current node to it; if not, we keep searching.

Here's the recursive version:

function recursiveSearchWithPath(nodeId, currentNode, currentPath = [currentNode]) {
  // Check if current node is the target
  if (currentNode.id === nodeId) {
    return {
      foundNode: currentNode,
      path: currentPath.map(n => ({ id: n.id, name: n.name }))
    };
  }
  
  // If no children, return null
  if (!currentNode.child) {
    return null;
  }
  
  // Recurse through each child
  for (const child of currentNode.child) {
    const result = recursiveSearchWithPath(nodeId, child, [...currentPath, child]);
    if (result) {
      return result;
    }
  }
  
  // Node not found in this branch
  return null;
}

// Test it
const recursiveResult = recursiveSearchWithPath(10, treeData);
console.log("Recursive found node:", recursiveResult?.foundNode);
console.log("Recursive path:", recursiveResult?.path);

Notes:

  • We use a default parameter for currentPath to start with the root node.
  • As soon as we find the target node in any child branch, we return the result immediately to avoid unnecessary recursion.

Both solutions will give you the full path from the root to your target node. Pick the one that fits better with your codebase—stack-based is better for very deep trees (to avoid stack overflow), while recursive is more readable for most cases.

内容的提问来源于stack exchange,提问作者Code Guru

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 09:04:34