简体   繁体   English

二进制搜索树平衡以获取高度

[英]Binary search Tree balanced working for getting height

I know this is pretty straight forward code but wondering how exactly the internal working is. 我知道这是非常简单的代码,但是想知道内部工作到底是怎么回事。

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

For my understanding, I added print statement but it results the following. 就我的理解而言,我添加了print语句,但结果如下。

printing root.left() prints this: 0 0 0 1 0 0 0 打印root.left()打印此内容: 0 0 0 1 0 0 0

printing root.right() prints this: 0 0 2 0 0 3 0 0 2 0 0 0 1 0 打印root.right()打印此内容: 0 0 2 0 0 3 0 0 2 0 0 0 1 0

Following is the Tree created in the main program: 以下是在主程序中创建的树:

TreeNode parent = new TreeNode(10);

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

How is this printing the above result and how is it working. 如何打印以上结果以及它如何工作。 If anyone can explain me with the above example, it would really help me. 如果有人能用上面的例子解释我,那将对我有帮助。

I know how traversals work and how to print the tree but I really want to understand the above output. 我知道遍历如何工作以及如何打印树,但是我真的很想了解上面的输出。 If anyone can help then it would be great. 如果有人可以帮助,那就太好了。

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

You should create a function that outputs information about the tree. 您应该创建一个输出有关树的信息的函数。 For example, this function does a preorder traversal, showing information about each node: 例如,此函数进行预遍历,显示有关每个节点的信息:

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

Call that function with ShowTree(tree, null, 0) . 使用ShowTree(tree, null, 0)调用该函数。 The resulting output will show the structure of the tree, and you can determine if the tree is balanced. 结果输出将显示树的结构,您可以确定树是否平衡。 It's a useful thing to have when you're developing tree code because you can do an insert, for example, then call ShowTree to see if the insert worked as expected. 开发树代码时,这是很有用的,因为您可以执行插入操作,例如,然后调用ShowTree来查看插入操作是否按预期工作。

Update 更新

The code's output is a little strange because your print statement results in a recursive call. 代码的输出有些奇怪,因为您的print语句会导致递归调用。 So every node below the current node ends up getting printed multiple times. 因此,当前节点下的每个节点最终都会多次打印。

I think you want to do this: 我认为您想这样做:

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

That way you won't get the multiple recursive calls that produce the strange output. 这样,您将不会获得产生奇怪输出的多个递归调用。

More info 更多信息

The reason you're seeing those extra recursive calls is because you're calling getHeight(root.left) twice. 之所以看到这些额外的递归调用,是因为您两次调用了getHeight(root.left) Let's say your tree looks like this: 假设您的树看起来像这样:

       root
      /
   child
   /
grandchild

So you call getHeight(root) . 因此,您调用getHeight(root) Then: 然后:

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
...

You see where the problem is? 您知道问题出在哪里吗? getHeight(grandchild) is called again! 再次调用getHeight(grandchild) Every time your print statement calls getHeight , it has to walk every descendant node. 每当您的print语句调用getHeight ,它必须遍历每个后代节点。 So the height of every node is output multiple times. 因此,每个节点的高度被多次输出。 The deeper the node is in the tree, the more often it will be output. 节点在树中的深度越深,输出的频率就越高。

The change I suggested in my update above prevents that by ensuring that no node is visited more than once. 我在上面的更新中建议的更改可以通过确保没有节点被多次访问来防止这种情况。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM