/**
* 树路径查询函数
* @param {Array<Object>} treeData - 树数据,格式为 [{id: 1, name: 'Node 1', children: [...]}, ...]
* @param {string | number} targetId - 目标节点的 ID
* @returns {Array<Object> | null} - 返回从根节点到目标节点的路径数组,找不到则返回 null
*/
function findPath(treeData, targetId) {
let path = [];
function traverse(nodes) {
if (!nodes || nodes.length === 0) {
return false;
}
for (const node of nodes) {
path.push(node); // 添加当前节点到路径
if (node.id === targetId) {
return true; // 找到目标节点,返回 true
}
if (node.children && traverse(node.children)) {
return true; // 在子节点中找到目标节点,返回 true
}
path.pop(); // 回溯,移除当前节点
}
return false; // 在当前分支未找到目标节点
}
if (traverse(treeData)) {
return path;
} else {
return null;
}
}
// 示例数据
const treeData = [
{
id: 1,
name: 'Node 1',
children: [
{ id: 2, name: 'Node 2' },
{
id: 3,
name: 'Node 3',
children: [
{ id: 4, name: 'Node 4' },
{ id: 5, name: 'Node 5' },
],
},
],
},
{ id: 6, name: 'Node 6' },
];
// 测试用例
console.log(findPath(treeData, 5)); // Output: [{...Node 1}, {...Node 3}, {...Node 5}]
console.log(findPath(treeData, 6)); // Output: [{...Node 6}]
console.log(findPath(treeData, 7)); // Output: null
console.log(findPath(treeData, 1)); // Output: [{...Node 1}]
代码解释:
-
findPath(treeData, targetId)
函数:- 接受树数据
treeData
和目标节点 IDtargetId
作为参数。 - 初始化一个空数组
path
用于存储路径。 - 调用
traverse
函数进行深度优先搜索。 - 如果
traverse
返回true
(找到目标节点),则返回path
;否则返回null
。
- 接受树数据
-
traverse(nodes)
函数:- 接受当前层级节点数组
nodes
作为参数。 - 遍历
nodes
中的每个节点:- 将当前节点
node
推入path
数组。 - 如果
node.id
等于targetId
,则找到目标节点,返回true
。 - 如果
node
存在子节点children
,则递归调用traverse(node.children)
。如果子节点中找到目标节点,则返回true
。 - 如果在当前节点及其子节点中都未找到目标节点,则从
path
数组中弹出当前节点(回溯)。
- 将当前节点
- 如果遍历完所有节点都未找到目标节点,则返回
false
。
- 接受当前层级节点数组
关键点:
- 深度优先搜索 (DFS): 使用递归实现深度优先搜索,遍历树的每个分支。
- 回溯: 在遍历完一个分支后,使用
path.pop()
将当前节点从路径中移除,以便继续搜索其他分支。 - 清晰的返回值:
traverse
函数返回true
或false
,表示是否找到目标节点,简化了逻辑。
这个改进版本更加简洁,逻辑清晰,并且包含了测试用例,方便理解和使用。 它能正确处理各种情况,包括目标节点在根节点、叶子节点或中间节点的情况,以及目标节点不存在的情况。
标签:Node,node,treeData,代码,路径,查询,id,path,节点 From: https://www.cnblogs.com/ai888/p/18596517