二进制搜索树平衡工作以获得高度

时间:2014-05-02 04:48:29

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

我知道这是非常直接的代码,但想知道内部工作的确切程度。

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++;
    }

1 个答案:

答案 0 :(得分:2)

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

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时,它都必须遍历每个后代节点。因此每个节点的高度输出多次。节点在树中越深,输出的频率就越高。

我在上面的更新中建议的更改可以确保不会多次访问任何节点。