递归以遍历二叉树Javascript的所有嵌套子节点

时间:2016-06-06 01:11:41

标签: javascript recursion binary-tree

我正在玩二叉树。我试图使用递归来查找所有嵌套子项的值并将所有值推送到数组中。我从左边的树开始看它是否有效。我试图调用childrenArray(),但控制台说没有定义childrenArray()。当我问if(typeof BinaryTree.prototype.childrenArray === 'function')时,它返回true。请教我并告诉我为什么我无法执行我的代码?

var Tree = function(value) {
  if (!(this instanceof Tree)) {
    return new Tree(value);
  }
  this.value = value;
  this.children = [];
};

Tree.prototype.addChild = function(value) {
  var child = new Tree(value);
  this.children.push(child);
};

Tree.prototype.contains = function(value) {
  if (this.value === value) {
    return true;
  } else {
    for (var i = 0; i < this.children.length; i++) {
      if (this.children[i] && this.children[i].contains(value)) {
        return true;
      }
    }
    return false;
  }
};


var BinaryTree = function(value) {
  if (!(this instanceof BinaryTree)) {
    return new BinaryTree(value);
  }
  Tree.call(this, value);
};
BinaryTree.prototype = Object.create(Tree.prototype);

BinaryTree.prototype.addChild = function(value) {
  if (value < this.value) {
    if (this.children[0] === undefined) {
      this.children[0] = new BinaryTree(value);
    }
    this.children[0].addChild(value);
  } else if (value > this.value) {
    if (this.children[1] === undefined) {
      this.children[1] = new BinaryTree(value);
    }
    this.children[1].addChild(value);
  }
};
BinaryTree.prototype.contains = function(value) {
  if (value < this.value) {
    if (this.children[0] === undefined) {
      return false;
    }
    return this.children[0].contains(value);
  } else if (value > this.value) {
    if (this.children[1] === undefined) {
      return false;
    }
    return this.children[1].contains(value);
  }
};

var a = new BinaryTree();
a.value = 10;
a.addChild(4);
a.addChild(11);
a.addChild(3);

BinaryTree.prototype.childrenArray = function() {
  var results = [];

  if (this.value) {
    results.push(this.value);
  }

  if (this.children[0].length === 0) {

    return results;
  }

  for (var i = 0; i < this.children[0].children.length; i++) {
    if (this.children[i].value) {
      results.push(this.children[i].value);
      return this.childrenArray();
    }
  }

};

a.childrenArray();

1 个答案:

答案 0 :(得分:0)

正如 @melpomene 所提到的,您正在调用childArray,但您没有在任何地方定义它。我假设行return childArray();错误地结束了那里,你可能意味着以递归方式返回root的左子句childrenArray

我想提一下你的循环本身(没有递归调用):

for(var i = 0; i < this.children[0].children.length; i++) { // <-- you are iterating over the children of root's left child
     if(this.children[i].value) { // <-- but you are accessing root's current child
        results.push(this.children[i].value);
     }
}

有点令人困惑。您正在迭代root的左孩子的子项 children[0].children,但是在每次迭代中,您检查 root的子项自己children[i]是否有值,你推高了这个价值。 这是不正确的,并且如果例如根只有一个具有两个子节点的左子节点(i将超出边界),则会中断。

以下是解决此问题的方法。在您的案例中打印左树的递归可以分解为以下情况:

  1. 如果当前节点没有值,则返回空数组
  2. 否则如果当前节点没有子节点,则返回仅包含当前值的数组
  3. 否则,如果当前节点有一个左子节点,则递归运行childrenArray并将结果添加到results数组
  4. 这是看起来的样子:

    BinaryTree.prototype.childrenArray = function() {
      var results = [];
    
      // case 1:
      if (this.value === undefined) {
        return results;
      }
    
      // case 2:
      results.push(this.value);
      if (this.children.length === 0) {
        return results;
      }
    
      // case 3:
      var leftChild = this.children[0];
      if (leftChild) {
        results = results.concat(leftChild.childrenArray());
      }
    
      /* add code here for the right child to complete your function */
    
      return results;
    };
    

    完整示例:

    var BinaryTree = function(value) {
      this.value = value;
      this.children = [];
    };
    
    BinaryTree.prototype.addChild = function (value) {
      if (value < this.value) {
        if (this.children[0] === undefined) {
          this.children[0] = new BinaryTree(value);
        }
        this.children[0].addChild(value);
      } else if (value > this.value) {
        if (this.children[1] === undefined) {
          this.children[1] = new BinaryTree(value);
        }
        this.children[1].addChild(value);
      }
    };
    
    BinaryTree.prototype.childrenArray = function() {
      var results = [];
    
      // case 1:
      if (this.value === undefined) {
        return results;
      }
    
      // case 2:
      results.push(this.value);
      if (this.children.length === 0) {
        return results;
      }
    
      // case 3:
      var leftChild = this.children[0];
      if (leftChild) {
        results = results.concat(leftChild.childrenArray());
      }
    
      /* add code here for the right child to complete your function */
    
      return results;
    };
    
    var a = new BinaryTree(10);
    a.addChild(4);
    a.addChild(11);
    a.addChild(3);
    
    console.log(a.childrenArray()); // [10, 4, 3]

    最后一件事,根据您的插入逻辑(如果较小则向左插入,如果较大则向右插入),您构建的是Binary Search Tree而不是Binary Tree。二叉树不遵循任何特定的插入逻辑。请查看this question以获取说明