【问题标题】:Calculate Height/Depth Of Binary Tree Javascript计算二叉树Javascript的高度/深度
【发布时间】:2022-01-25 08:05:39
【问题描述】:

我只是一个初学者,所以如果错误太明显,我很抱歉。

我的两个问题是:

  1. 我们学校提供的代码中this.root是什么;
  2. 如何实现.height 方法来测量树的深度。

解释: 我们在课堂上得到了这个代码:

function BinarySearchTree(value) {
  this.value = value;
  this.right = null;
  this.left = null;
}

BinarySearchTree.prototype.add = function(value) {
  let newLeaf = new BinarySearchTree(value)

  if(value > this.value){
    this.right === null? this.right = newLeaf : this.right.add(value)
  } else {
    this.left === null? this.left = newLeaf : this.left.add(value)
  }
};

我们应该写一个方法来计算二叉树的高度/深度。现在,在练习时,我看到了一些奇怪的东西。在创建空二叉树的新节点后,第一个节点最终完全为空,而它继续在第一个空的左侧创建一个新节点。好吧,不是空的,但其值为undefined。这是一种期望的行为吗?

let newTree = new BinarySearchTree
>undefined

newTree.add(7)
>undefined

newTree.add(3)
>undefined

newTree.add(5)
>undefined

newTree
>BinarySearchTree {value: undefined, right: null, left: BinarySearchTree}
  left: BinarySearchTree {value: 7, right: null, left: BinarySearchTree}
  right: null
  value: undefined
  [[Prototype]]: Object

现在,考虑到.add 方法的测试通过了,显然我在这种情况下可能是错的,因为这是课堂上老师提供给我们的代码。 这是我一直在网上找到的代码,我对.heigth 方法的代码没有深入了解的原因是因为我无法实现this.root

function Node(val){
  this.value = val;
  this.left = null;
  this.right = null;
}


function BinarySearchTree(){
  this.root = null;
}

我应该如何继续使用.height 方法? 如果有帮助,以下是测试:

describe('Binary Search Tree', function() {
  var binarySearchTree;

  beforeEach(function() {
    binarySearchTree = new BinarySearchTree(5);
  });

  it('should have methods named "add", "contains", "depthFirstPre", "depthFirstIn", "depthFirstPost", "breadthFirst"', function() {
    expect(binarySearchTree.add).to.be.a("function");
  });

  it('should add values at the correct location in the tree', function(){
    binarySearchTree.add(2);
    binarySearchTree.add(3);
    binarySearchTree.add(7);
    binarySearchTree.add(6);
    expect(binarySearchTree.left.right.value).to.equal(3);
    expect(binarySearchTree.right.left.value).to.equal(6);
  });

  it('height method should return correct height', function() {
    binarySearchTree.left = new BinarySearchTree(3);
    binarySearchTree.left.left = new BinarySearchTree(1);
    expect(binarySearchTree.height()).to.eql(2);

    binarySearchTree.left.left.right = new BinarySearchTree(2);
    expect(binarySearchTree.height()).to.eql(3);

    binarySearchTree.left.left.left = new BinarySearchTree(0);
    expect(binarySearchTree.height()).to.eql(3);

    binarySearchTree.right = new BinarySearchTree(8);
    expect(binarySearchTree.height()).to.eql(3);
  });
}

再次,我为一个很长的问题道歉。我试图写下关于我的问题的所有相关信息。 节日快乐!

【问题讨论】:

  • 在 BinarySearchTree.prototype.add 中,应该处理 this.value == null(根节点为 null 时)的情况。
  • "创建一个空二叉树的新节点" - 你们学校提供的第一个数据结构的问题是它不能代表一棵空树.一旦你创建了new BinarySearchTree,你就会得到一棵树,它由一个值为undefined 的节点(根节点)组成。所以是的,从BinarySearchTree 中分离出Node 的想法是正确的方法。但既然你的老师希望你使用他们的方法,就考虑成为一个NonEmptyBinarySearchTree,它的高度总是至少为 1。
  • @Bergi 感谢您的回复。如果我的 BST 和 Node 没有分开,我应该如何继续写 function height(node){...
  • @jh316 感谢您的回复。很遗憾,我们不允许更改学校提供的代码。

标签: javascript binary-tree nodes


【解决方案1】:

我们学校提供的代码中this.root是什么

您学校的模板代码不管理树的根,因此必须由驱动程序代码在变量中进行管理。在测试代​​码中,这个变量被命名为binarySearchTree,在第二个(2-class)实现中它确实被称为this.root

现在,在练习时,我看到了一些奇怪的东西。在创建空二叉树的新节点后,第一个节点最终完全为空 [...] 这是一种期望的行为吗?

不,这不是我们想要的行为。模板代码不提供空二叉树的概念。它希望您创建具有至少一个值的树,该值应作为参数提供给构造函数。调用构造函数时不打算省略参数。

2 类实现提供了 树的概念。但是学校的模板代码没有;如果你想要一棵空树,你只需要声明binarySearchTree = null。但缺点很明显:您不能使用类的 方法 为其添加值。获取树中第一个值的唯一方法是调用构造函数并将构造的对象分配给您的binarySearchTree 变量。因此,将第一个值添加到树需要与添加其他值不同的方法。这也是您在测试代码中看到的:第一个值作为参数添加到 constructor - always 使用参数调用 - 而其他值通过调用add 方法添加。这是一个遗憾,也确实显示了模板代码的局限性。

如何实现.height 方法来测量树的深度。

这个想法是你使用递归:

如果有左孩子,通过递归得到左子树的高度。如果没有,则使用 -1 作为默认值,因为它是一个空子树,以及 empty trees have a height of -1。在右侧做同样的事情。获取这两个值中的最大值,因为只有两者中较高的子树才能确定树的高度。最后在这个结果上加一个,以便考虑当前节点。

BinarySearchTree.prototype.height = function() {
  return 1 + Math.max(
    this.left  !== null ? this.left.height()  : -1,
    this.right !== null ? this.right.height() : -1
  );
};

同样,由于学校模板代码的限制,您只能在至少有一个节点的树上运行height 方法。

为了完整起见,等效的 2 类会将上述代码放在 Node 类上,并在 BinarySearchTree 类上添加一个包装器方法,如下所示:

Node.prototype.height = function() {
  return 1 + Math.max(
    this.left  !== null ? this.left.height()  : -1,
    this.right !== null ? this.right.height() : -1
  );
};

BinarySearchTree.prototype.height = function() {
  return this.root === null ? -1 : root.height();
}

【讨论】:

  • 非常感谢您提供如此详细的解释。是的,我可以在网上找到两类实现作为 BST 的方法。不幸的是,我太缺乏经验而无法更改该代码以使其适用于我的情况,但现在,我真的认为我理解它了。 @trincot 先生,再次,非常非常感谢您!
  • 一棵空树的高度为0,具有单个节点的树的高度为1。不知道为什么要使用-1
  • @Bergi,参见Wikipedia on tree data structure“通常,一棵空树(没有节点的树,如果允许的话)的高度为 -1。”
猜你喜欢
  • 1970-01-01
  • 2010-12-24
  • 2013-02-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-15
相关资源
最近更新 更多