英文:
Implement a method in Javascript that calculates the level of a tree node
问题
给定一个如下所示的树 - 请注意,这不是二叉树:
根节点
/ \
A B
/ \ / \
C D E F
/ \ \
G H I
我想要编写一个方法,该方法返回我调用它时节点的层级。例如,当调用 C.getLevel()
时,我期望返回值为 2,假设根节点的层级为 0。
每个节点只有两个属性:名称和其直接子节点的数组。
由于我在处理一棵树,我有一种感觉我需要递归解决这个问题。因此,在第一步中,我需要找出一个退出条件 - 何时会返回我的方法?很可能是当没有子节点时。
我不太确定如何解决这个问题,但为了让我们有点东西可以一起工作,我将发布一个起始方法:
getLevel(level = 0) {
if (this.children.length === 0) {
return level;
}
for (let child of this.children) {
level = child.getLevel(level + 1);
}
}
有人可以帮助我解决这个问题吗?
英文:
Given a tree such as the following - please note this is NOT a binary tree:
root
/ \
A B
/ \ / \
C D E F
/ \ \
G H I
I would like to write a method, which returns the level of the node I call the method on. For example, when calling C.getLevel()
I am expecting the return value 2, assuming the level of the root node is 0.
Each node has but two properties: a name and an array of its direct children.
Since I am working with a tree here, I have a feeling I need to solve this issue recursively. So, in a first step, I have to figure out an exit condition - when is my method going to return? Most likely when there are no children.
I don't really have a good approach for this issue, but just to give us something to work with, I'll post a start method:
getLevel(level = 0) {
if (this.children.length === 0) {
return level;
}
for (let child of this.children) {
level = child.getLevel(level + 1);
}
}
Can somebody help me figure this out?
答案1
得分: 1
你需要从根节点开始搜索,然后查找节点。这可以基于作为参数给定的节点实例,也可以基于目标节点的名称(在示例中是 "C")进行搜索。
请注意,我更喜欢将这个方面称为 深度 而不是 级别,但它是相同的概念。
以下是一个通过名称搜索节点的实现,从根节点开始(我将方法命名为 getDepth
):
class Node {
constructor(name, ...children) {
this.name = name;
this.children = children;
}
getDepth(name) {
if (this.name == name) return 0;
for (const child of this children) {
const level = child.getDepth(name);
if (level >= 0) return level + 1;
}
return -1; // 找不到节点
}
}
// 构建示例树
const root = new Node("root",
new Node("A",
new Node("C",
new Node("G"),
new Node("H"),
new Node("I")
),
new Node("D")
),
new Node("B",
new Node("E"),
new Node("F")
)
);
const level = root.getDepth("C");
console.log(level); // 2
你提到了注释中的相反方法签名,这也是一种可能性。就像这样:
class Node {
constructor(name, ...children) {
this.name = name;
this.children = children;
}
getDepthWithRespectTo(root) {
if (this === root) return 0;
for (const parent of root.children) {
const level = this.getDepthWithRespectTo(parent);
if (level >= 0) return level + 1;
}
return -1; // 找不到节点
}
}
// 构建示例树,并保留对节点 "C" 的引用
let node;
const root = new Node("root",
new Node("A",
node = new Node("C",
new Node("G"),
new Node("H"),
new Node("I")
),
new Node("D")
),
new Node("B",
new Node("E"),
new Node("F")
)
);
const level = node.getDepthWithRespectTo(root);
console.log(level); // 2
英文:
You need to start the search from the root and then look to find the node. This could either be based on a node instance that is given as argument, or on a name that the target node has ("C" in the example).
Note that I prefer to call this aspect depth instead of level -- but it's the same thing.
Here is an implementation that searches for the node by name, starting at the root (I named the method getDepth
):
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
class Node {
constructor(name, ...children) {
this.name = name;
this.children = children;
}
getDepth(name) {
if (this.name == name) return 0;
for (const child of this.children) {
const level = child.getDepth(name);
if (level >= 0) return level + 1;
}
return -1; // Not found here
}
}
// Build the example tree
const root = new Node("root",
new Node("A",
new Node("C",
new Node("G"),
new Node("H"),
new Node("I")
),
new Node("D")
),
new Node("B",
new Node("E"),
new Node("F")
)
);
const level = root.getDepth("C");
console.log(level); // 2
<!-- end snippet -->
You mentioned an opposite method signature in comments, which is also a possibility. Like this:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
class Node {
constructor(name, ...children) {
this.name = name;
this.children = children;
}
getDepthWithRespectTo(root) {
if (this === root) return 0;
for (const parent of root.children) {
const level = this.getDepthWithRespectTo(parent);
if (level >= 0) return level + 1;
}
return -1; // Not found here
}
}
// Build the example tree, and keep a reference to node "C"
let node;
const root = new Node("root",
new Node("A",
node = new Node("C",
new Node("G"),
new Node("H"),
new Node("I")
),
new Node("D")
),
new Node("B",
new Node("E"),
new Node("F")
)
);
const level = node.getDepthWithRespectTo(root);
console.log(level); // 2
<!-- end snippet -->
答案2
得分: 0
因为你无论如何都要迭代整个树,所以一次性预先计算所有节点的深度可能会更容易:
function setDepth(node, depth) {
node.depth = depth
for (let c of node.children)
setDepth(c, depth + 1)
}
setDepth(root, 0)
然后只需选择 someNode.depth
。
英文:
Since you're going to iterate the whole tree anyway, it might be easier to precompute depths for all nodes at once:
function setDepth(node, depth) {
node.depth = depth
for (let c of node.children)
setDepth(c, depth + 1)
}
setDepth(root, 0)
and then just pick someNode.depth
答案3
得分: 0
class TreeNode {
constructor(value) {
this.value = value;
this.children = [];
}
addChild(child) {
this.children.push(child);
}
}
function calculateNodeLevel(root, targetValue) {
if (root.value === targetValue) {
return 0; // Found the target node at the root level
}
for (let child of root.children) {
const level = calculateNodeLevel(child, targetValue);
if (level !== -1) {
return level + 1; // Found the target node in a child subtree
}
}
return -1; // Target node not found in the tree
}
// Example usage:
const tree = new TreeNode(1);
const child1 = new TreeNode(2);
const child2 = new TreeNode(3);
const grandchild = new TreeNode(4);
child2.addChild(grandchild);
tree.addChild(child1);
tree.addChild(child2);
console.log(calculateNodeLevel(tree, 1)); // Output: 0
console.log(calculateNodeLevel(tree, 2)); // Output: 1
console.log(calculateNodeLevel(tree, 3)); // Output: 1
console.log(calculateNodeLevel(tree, 4)); // Output: 2
console.log(calculateNodeLevel(tree, 5)); // Output: -1 (Node not found)
英文:
class TreeNode {
constructor(value) {
this.value = value;
this.children = [];
}
addChild(child) {
this.children.push(child);
}
}
function calculateNodeLevel(root, targetValue) {
if (root.value === targetValue) {
return 0; // Found the target node at the root level
}
for (let child of root.children) {
const level = calculateNodeLevel(child, targetValue);
if (level !== -1) {
return level + 1; // Found the target node in a child subtree
}
}
return -1; // Target node not found in the tree
}
// Example usage:
const tree = new TreeNode(1);
const child1 = new TreeNode(2);
const child2 = new TreeNode(3);
const grandchild = new TreeNode(4);
child2.addChild(grandchild);
tree.addChild(child1);
tree.addChild(child2);
console.log(calculateNodeLevel(tree, 1)); // Output: 0
console.log(calculateNodeLevel(tree, 2)); // Output: 1
console.log(calculateNodeLevel(tree, 3)); // Output: 1
console.log(calculateNodeLevel(tree, 4)); // Output: 2
console.log(calculateNodeLevel(tree, 5)); // Output: -1 (Node not found)
In this example, the TreeNode class represents a node in the tree, and it has a value property to store the value of the node and a children array to store its child nodes.
The calculateNodeLevel function takes a root node and a targetValue as input. It recursively traverses the tree starting from the root and checks if the value of each node matches the targetValue. If a match is found, it returns the level of that node (0 for the root level, 1 for its children, and so on). If the targetValue is not found in the tree, it returns -1.
In the example usage section, a simple tree is created, and the calculateNodeLevel function is called with different target values to demonstrate its usage and output.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论