【问题标题】:Binary search Tree balanced working for getting height二叉搜索树平衡工作以获得高度
【发布时间】:2014-05-02 04:48:28
【问题描述】:

我知道这是非常简单的代码,但想知道内部工作的具体情况。

public static int getHeight(TreeNode root) {
        if (root == null) {
            return 0;
        }
            System.out.print(getHeight(root.left) +"\t");
        return Math.max(getHeight(root.left), getHeight(root.right)) + 1;
    }

据我了解,我添加了 print 语句,但结果如下。

打印 root.left() 会打印:0 0 0 1 0 0 0

打印 root.right() 打印:0 0 2 0 0 3 0 0 2 0 0 0 1 0

以下是主程序中创建的树:

TreeNode parent = new TreeNode(10);

        parent.insertInOrder(2);
        parent.insertInOrder(13);
        parent.insertInOrder(5);
        parent.insertInOrder(6);
        parent.insertInOrder(15);
        parent.insertInOrder(6);

如何打印上述结果以及它是如何工作的。如果有人能用上面的例子解释我,那真的对我有帮助。

我知道遍历是如何工作的以及如何打印树,但我真的很想了解上面的输出。如果有人可以提供帮助,那就太好了。

void setLeftChild(TreeNode left)
    {
        this.left = left;
        if(left == null)
        {
            left.parent = this;
        }
    }

    void setRightChild(TreeNode right)
    {
        this.right = right;
        if(right == null)
        {
            right.parent =  this;
        }
    }

    void insertInOrder(int d)
    {
        if(d <= data)
        {
            if(left == null)
            {
                setLeftChild(new TreeNode(d));
            }
            else
            {
                left.insertInOrder(d);
            }
        }
        else{
            if(right == null)
            {
                setRightChild(new TreeNode(d));
            }
            else{
                right.insertInOrder(d);
            }
        }
        size++;
    }

【问题讨论】:

  • 树平衡了吗? insertInOrder 是如何工作的?
  • size 是全局变量吗?你在这里做任何平衡还是不平衡的bst?作为旁注,使用迭代代码进行插入。如果可以的话,尽量避免递归。他们很慢。
  • 我正在尝试平衡 bst 和 size isnt global
  • 平衡的代码的哪一部分?如果大小不是全局的,它的值将如何在递归调用中传播。您必须将它作为参数传递给递归函数。
  • 我的问题与您的问题并不完全相关。其余代码没有问题

标签: java algorithm data-structures tree binary-search-tree


【解决方案1】:

您应该创建一个输出有关树的信息的函数。例如,这个函数进行前序遍历,显示每个节点的信息:

public static void ShowTree(TreeNode root, TreeNode parent, depth)
{
    if (root == null) return;

    // output 'depth' spaces.
    // The indentation will help show the structure of the tree.        

    // output node value, and parent (if parent not null)

    // Traverse the left node
    ShowTree(root.left, root, depth+1);

    // Traverse the right node
    ShowTree(root.right, root, depth+1);
}

使用ShowTree(tree, null, 0) 调用该函数。结果输出将显示树的结构,您可以确定树是否平衡。在开发树代码时拥有它很有用,因为您可以执行插入操作,例如,然后调用 ShowTree 以查看插入是否按预期工作。

更新

代码的输出有点奇怪,因为您的print 语句会导致递归调用。因此,当前节点下方的每个节点最终都会被打印多次。

我想你想这样做:

int leftHeight = getHeight(root.left);
int rightHeight = getHeight(root.right);
// now output output leftHeight or rightHeight, or both
return Math.max(leftHeight, rightHeight) + 1;

这样你就不会得到产生奇怪输出的多个递归调用。

更多信息

您看到这些额外的递归调用的原因是您调用了两次getHeight(root.left)。假设您的树如下所示:

       root
      /
   child
   /
grandchild

所以你打电话给getHeight(root)。那么:

getHeight(child) is called in your print statement
getHeight(grandchild) is called in your print statement
getHeight(null) is called in your print statement
getHeight(grandchild) prints 0
getHeight(null) is called twice (once for the left node and once for the right node) in the return statement
getHeight(grandchild) returns 1
getHeight(child) prints 1
getHeight(grandchild) is called in the return statement
getHeight(null) is called in your print statement
getHeight(grandchild) prints 0
getHeight(grandchild) returns 1
getHeight(null) (the right node) is called in the return statement
...

你明白问题出在哪里了吗? getHeight(grandchild) 再次被调用!每次print 语句调用getHeight 时,它都必须遍历每个后代节点。所以每个节点的高度都会被输出多次。节点在树中越深,输出的频率就越高。

我在上面的更新中建议的更改通过确保没有节点被多次访问来防止这种情况发生。

【讨论】:

  • 我确实了解遍历和打印,但我想了解上面的代码和输出以及它的 wrkin
  • 您能解释一下递归是如何工作的以及为什么会有多个递归调用吗?树的左侧有 4 个节点,右侧有 2 个节点,所以总共应该有 6 个递归调用,对吧?
  • @fscore:查看我的最新更新。我建议你在调试器中单步执行你的代码,这样你就可以看到发生了什么。
  • 所以你的预遍历也计算了遍历时的深度,这使得很容易知道树的深度,如果高度差
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-12-18
  • 1970-01-01
  • 2012-05-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多