获取二叉搜索树的高度 - 堆栈溢出错误

Posted

技术标签:

【中文标题】获取二叉搜索树的高度 - 堆栈溢出错误【英文标题】:Get the height of a binary search tree - stack overflow error 【发布时间】:2021-10-16 20:26:20 【问题描述】:
BinarySearchTree.prototype.height = function () 
    if (this.right === null && this.left === null) return 1;
    var heightLeft = 0;
    var heightRight = 0;
    if (this.left != null)
        heightLeft = this.height(this.left);
    if (this.right != null)
        heightRight =this.height(this.right);
    if (heightLeft > heightRight) 
        return heightLeft + 1;
     else 
        return heightRight + 1;
    
; 

我需要获取 BST 的高度。我理解这个理论,但我希望根算作 1 而不是 0。

如果我有这样的 BST:

             16             ---> lvl1
          /      \
        6         23        ---> lvl2
      /  \       /   \
     2    14    17    31    ---> lvl3
      \
       5                    ---> lvl4 

...那么高度将是 4.

我的函数遇到堆栈溢出。我怎样才能让它发挥作用?

【问题讨论】:

你的构造函数BinarySearchTree是什么样的? 【参考方案1】:

这是一个使用递归的好问题。您将需要遍历三个分支中的每个分支并将最大高度保存在一个变量中。如果您发现更高的高度,请在变量中替换它:

BinarySearchTree.prototype.height = function () 

  let maxHeight = 1;

  const goThroughBranch = (branch, lvl = 1) => 

    if (branch.right !== null)
      goThroughBranch(branch.right, lvl+1);

    if (branch.left !== null)
      goThroughBranch(branch.left, lvl+1);

    if (lvl > maxHeight)
      maxHeight = lvl;
  ;
  
  goThroughBranch(this);

  return maxHeight;
; 

【讨论】:

这种编码风格不如提问者试图做的那样有吸引力。您的答案是推广具有副作用的函数,而 Asker 考虑到了 递归函数。【参考方案2】:

您的代码中只有一个问题:

height 方法不带参数,但您的递归调用传递参数:

heightLeft = this.height(this.left);

相反,您应该调用this.left 上的方法,而不是this

heightLeft = this.left.height();

右侧需要进行类似的更改。

假设BinarySearchTree 实例具有属性leftright,这些更改本身就是BinarySearchTree(或null)的实例,那么它将起作用。

我建议使用更现代的class 语法来定义BinarySearchTree,并使用三元运算符和Math.max 缩短代码。

这是我编写该类的方式:

class BinarySearchTree 
    constructor(value, left=null, right=null) 
        this.value = value;
        this.left = left;
        this.right = right;
    
    static from(firstValue, ...values) 
        if (!arguments.length) return;
        const root = new BinarySearchTree(firstValue);
        for (let value of values) root.insert(value);
        return root;
    
    * [Symbol.iterator]() 
        if (this.left) yield * this.left;
        yield this.value;
        if (this.right) yield * this.right;
    
    insert(value) 
        if (value < this.value) 
            if (this.left) 
                this.left.insert(value);
             else 
                this.left = new BinarySearchTree(value);
            
         else if (this.right) 
            this.right.insert(value);
         else 
            this.right = new BinarySearchTree(value);
        
    
    height() 
        return 1 + Math.max(this.left  ? this.left.height()  : 0, 
                            this.right ? this.right.height() : 0) 
    


// Create the tree given as example in the question:
const tree = BinarySearchTree.from(16, 6, 23, 2, 14, 17, 31, 5);

console.log("inorder traversal is", ...tree);
console.log("height is", tree.height());

【讨论】:

以上是关于获取二叉搜索树的高度 - 堆栈溢出错误的主要内容,如果未能解决你的问题,请参考以下文章

二叉树之二叉搜索树的基本操作实现

红黑树——一个自平衡的二叉搜索树

二叉搜索树的平均查找长度及时间复杂度

二叉平衡搜索树——AVL树

实现递归 Void 函数(查找二叉搜索树的高度)

二叉搜索树