JavaScript 递归树搜索函数未检测到嵌套子项
JavaScript Recursive Tree Searching Function Not Detecting Nested Children
尝试创建一个递归函数来正确搜索树 class 及其所有后代的值,returns 如果找到该值则为真,否则为假。
特别重要的是递归 contains() 函数。试图让代码通过 linter。我只收到一个关于未检测到嵌套子项的错误。其他一切都过去了。
我的代码:
/* eslint-disable no-trailing-spaces */
/* eslint-disable no-unused-vars */
class Tree {
constructor(value) {
this.value = value;
this.children = [];
}
// Adds a new Tree node with the input value to the current Tree node
addChild(value) {
this.children.push(new Tree(value));
}
// Checks this node's children to see if any of them matches the given value
// Continues recursively until the value has been found or all of the children
// have been checked
contains(value) {
const thisNode = this;
function checkNode(node) {
if (node.value === value) {
return true;
}
if (node.children.length > 0) {
for (let i = 0; i < node.children.length; i++) {
return checkNode(node.children[i]);
}
}
return false;
}
return checkNode(thisNode);
}
}
module.exports = Tree;
这是测试它的文件:
/* eslint-disable no-undef */
const Tree = require('../src/tree');
describe('Tree', () => {
let tree;
beforeEach(() => {
tree = new Tree(true);
});
it('should have methods named "addChild" and "contains"', () => {
expect(typeof tree.addChild).toBe('function');
expect(typeof tree.contains).toBe('function');
});
it('should add children to the tree', () => {
tree.addChild(5);
expect(tree.children[0].value).toBe(5);
});
it('should return true for a value that the tree contains', () => {
tree.addChild(5);
expect(tree.contains(5)).toBe(true);
});
it('should return false for a value that was not added', () => {
tree.addChild(5);
expect(tree.contains(6)).toBe(false);
});
it('should be able to add children to a tree\'s child', () => {
tree.addChild(5);
tree.children[0].addChild(6);
expect(tree.children[0].children[0].value).toBe(6);
});
it('should correctly detect nested children', () => {
tree.addChild(5);
tree.addChild(6);
tree.children[0].addChild(7);
tree.children[1].addChild(8);
expect(tree.contains(7)).toBe(true);
expect(tree.contains(8)).toBe(true);
});
});
这里是 linting 错误:
Tree
✓ should have methods named "addChild" and "contains" (5ms)
✓ should add children to the tree (1ms)
✓ should return true for a value that the tree contains (3ms)
✓ should return false for a value that was not added (1ms)
✓ should be able to add children to a tree's child (1ms)
✕ should correctly detect nested children (9ms)
你无条件return里面的for-loop,所以你只检查第一个child。
for (let i = 0; i < node.children.length; i++) {
return checkNode(node.children[i]);
}
应该是
for (let i = 0; i < node.children.length; i++) {
if (checkNode(node.children[i])) return true;
}
我想,您的代码应该是这样的:
for (let childIndex = 0; childIndex < node.children.length; childIndex++) {
const foundInChildren = checkNode(node.children[childIndex]);
if (foundInChildren)
return true;
}
您的问题出在这段代码中:
if (node.children.length > 0) {
for (let i = 0; i < node.children.length; i++) {
return checkNode(node.children[i]);
}
}
这行代码将从函数中 return 无论第一个子节点的 checkNode 结果是真还是假。如果结果为假,则需要继续检查。
试试这个:
if (node.children.length > 0) {
for (let i = 0; i < node.children.length; i++) {
if (checkNode(node.children[i])) {
return true;
}
}
}
尝试创建一个递归函数来正确搜索树 class 及其所有后代的值,returns 如果找到该值则为真,否则为假。
特别重要的是递归 contains() 函数。试图让代码通过 linter。我只收到一个关于未检测到嵌套子项的错误。其他一切都过去了。
我的代码:
/* eslint-disable no-trailing-spaces */
/* eslint-disable no-unused-vars */
class Tree {
constructor(value) {
this.value = value;
this.children = [];
}
// Adds a new Tree node with the input value to the current Tree node
addChild(value) {
this.children.push(new Tree(value));
}
// Checks this node's children to see if any of them matches the given value
// Continues recursively until the value has been found or all of the children
// have been checked
contains(value) {
const thisNode = this;
function checkNode(node) {
if (node.value === value) {
return true;
}
if (node.children.length > 0) {
for (let i = 0; i < node.children.length; i++) {
return checkNode(node.children[i]);
}
}
return false;
}
return checkNode(thisNode);
}
}
module.exports = Tree;
这是测试它的文件:
/* eslint-disable no-undef */
const Tree = require('../src/tree');
describe('Tree', () => {
let tree;
beforeEach(() => {
tree = new Tree(true);
});
it('should have methods named "addChild" and "contains"', () => {
expect(typeof tree.addChild).toBe('function');
expect(typeof tree.contains).toBe('function');
});
it('should add children to the tree', () => {
tree.addChild(5);
expect(tree.children[0].value).toBe(5);
});
it('should return true for a value that the tree contains', () => {
tree.addChild(5);
expect(tree.contains(5)).toBe(true);
});
it('should return false for a value that was not added', () => {
tree.addChild(5);
expect(tree.contains(6)).toBe(false);
});
it('should be able to add children to a tree\'s child', () => {
tree.addChild(5);
tree.children[0].addChild(6);
expect(tree.children[0].children[0].value).toBe(6);
});
it('should correctly detect nested children', () => {
tree.addChild(5);
tree.addChild(6);
tree.children[0].addChild(7);
tree.children[1].addChild(8);
expect(tree.contains(7)).toBe(true);
expect(tree.contains(8)).toBe(true);
});
});
这里是 linting 错误:
Tree
✓ should have methods named "addChild" and "contains" (5ms)
✓ should add children to the tree (1ms)
✓ should return true for a value that the tree contains (3ms)
✓ should return false for a value that was not added (1ms)
✓ should be able to add children to a tree's child (1ms)
✕ should correctly detect nested children (9ms)
你无条件return里面的for-loop,所以你只检查第一个child。
for (let i = 0; i < node.children.length; i++) {
return checkNode(node.children[i]);
}
应该是
for (let i = 0; i < node.children.length; i++) {
if (checkNode(node.children[i])) return true;
}
我想,您的代码应该是这样的:
for (let childIndex = 0; childIndex < node.children.length; childIndex++) {
const foundInChildren = checkNode(node.children[childIndex]);
if (foundInChildren)
return true;
}
您的问题出在这段代码中:
if (node.children.length > 0) {
for (let i = 0; i < node.children.length; i++) {
return checkNode(node.children[i]);
}
}
这行代码将从函数中 return 无论第一个子节点的 checkNode 结果是真还是假。如果结果为假,则需要继续检查。
试试这个:
if (node.children.length > 0) {
for (let i = 0; i < node.children.length; i++) {
if (checkNode(node.children[i])) {
return true;
}
}
}