简体   繁体   中英

Recursive function not returning despite stop condition being met

I am trying to write a contains function on my Tree class to check if the tree contains a value or not. Although my stop condition is being met (verified by a console log), the function does not return true.

 class Tree { constructor (value) { this.value = value; this.children = []; } addChild (tree) { this.children.push(tree); return true; } contains (value) { if (this.value === value) { return true; } if (this.children.length === 0) return false; for (let tree of this.children) { tree.contains(value); } } } const tree = new Tree('hello'); const subTree = new Tree('world'); console.log(tree.addChild(subTree) === true); console.log(tree.contains('world') === true); 

You need to return the first true find from the children and at the end return false as default value.

 class Tree { constructor (value) { this.value = value; this.children = []; } addChild (tree) { this.children.push(tree); return true; } contains (value) { if (this.value === value) { return true; } if (this.children.length === 0) return false; for (let tree of this.children) { if (tree.contains(value)) { return true; } } return false; } } const tree = new Tree('hello'); const subTree = new Tree('world'); console.log(tree.addChild(subTree) === true); console.log(tree.contains('world') === true); 

You need to return a value inside the loop. Instead of just calling the tree.contains function, you need to check if the function returns true and return true if it does and return false after the for loop is complete.

 class Tree { constructor (value) { this.value = value; this.children = []; } addChild (tree) { this.children.push(tree); return true; } contains (value) { if (this.value === value) { console.log('foobar') //logs 'foobar' when tests are run return true; } if (this.children.length === 0) return false; for (let tree of this.children) { if(tree.contains(value)){ return true; } } return false; } } var tree = new Tree('oak'); console.log(tree.contains('oak')); var tree2 = new Tree('birch'); tree.addChild(tree2); var tree3 = new Tree('pine'); tree.addChild(tree3); console.log(tree.contains('birch')&&tree.contains('pine')); 

The problem is that this recursive function only works on its first call, in the unlikely scenario when the tree's root contains the value. However, if a child of the root has the value, the results of that finding aren't passed up the call stack. Here's a code example:

 class Tree { constructor (value) { this.value = value; this.children = []; } addChild (tree) { this.children.push(tree); return true; } contains (value) { // if this node has the value, tell its parent if (this.value === value) { return true; } // this node doesn't have the value, but if any // of its children do, report that to the parent for (let tree of this.children) { if (tree.contains(value)) { return true; } } // neither this node nor any of its descendents have // the value; the search is exhausted on this tree return false; } } const tree = new Tree("a"); const subTree = new Tree("b") tree.addChild(subTree); tree.addChild(new Tree("c")); subTree.addChild(new Tree("d")); console.log(tree.contains("a")); console.log(tree.contains("b")); console.log(tree.contains("c")); console.log(tree.contains("d")); console.log(tree.contains("e")); 

The example tree looks like this:

      a
    /   \ 
   b     c
  /
 d    

Let's walk through a search for node d :

a: a doesn't have d, enters the loop and asks b if it has d
    b: b doesn't have d, enters the loop and asks d if it has d
        d: d has d and immediately reports to b that it does
    b: b immediately reports to a that it has d
a: a immediately reports to the global scope that it has d

Let's walk through a search for node e :

a: a doesn't have e, enters the loop and asks b if it has e
    b: b doesn't have e, enters the loop and asks d if it has e
        d: d doesn't have e and has no children to search and returns false to b
    b: b's loop is exhausted and reports false to a
a: a has another child, c, and asks it if it has d
    c: c doesn't have e and has no children to search and returns false to a
a: a's loop is exhausted and reports false to the global scope

Incidentally, you can see that this tree's search time is linear time complexity, in contrast to balanced binary search trees , which have O(log n) search time complexity. BSTs might not be able to organize the same kind of data you may be using this tree to store, though, so I only mention it in passing.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM