如何确定二叉树是否平衡?

时间:2009-04-13 01:58:07

标签: java algorithm data-structures binary-tree

这些学年已经有一段时间了。在医院找到了IT专家的工作。现在试着去做一些实际的编程。我现在正在研究二叉树,我想知道确定树是否高度平衡的最佳方法是什么。

我在考虑这个问题:

public boolean isBalanced(Node root){
    if(root==null){
        return true;  //tree is empty
    }
    else{
        int lh = root.left.height();
        int rh = root.right.height();
        if(lh - rh > 1 || rh - lh > 1){
            return false;
        }
    }
    return true;
}

这是一个很好的实施吗?或者我错过了什么?

27 个答案:

答案 0 :(得分:160)

在搜索其他内容时偶然发现了这个旧问题。我注意到你从来没有得到完整的答案。

解决这个问题的方法是首先为你要编写的函数编写一个规范。

规格:如果(1)它是空的,或者(2)它的左右儿童是高度平衡的并且左边树的高度在内,则一个结构良好的二叉树被称为“高度平衡”。右树的高度之一。

现在你已经有了规范,代码写起来很简单。只需遵循规范:

IsHeightBalanced(tree)
    return (tree is empty) or 
           (IsHeightBalanced(tree.left) and
            IsHeightBalanced(tree.right) and
            abs(Height(tree.left) - Height(tree.right)) <= 1)

将其翻译成您选择的编程语言应该是微不足道的。

奖励练习:这个天真的代码草图在计算高度时会遍历树太多次。你能提高效率吗?

超级练习:假设树大量不平衡。比如,一侧有一百万个节点,另一侧有三个节点。是否存在此算法打击堆栈的情况?你可以修复实现,以便它永远不会打击堆栈,即使给出了一个非常不平衡的树吗?

更新:Donal Fellows在他的回答中指出,人们可以选择“平衡”的不同定义。例如,可以采用更严格的“高度平衡”定义,并要求最近的空子的路径长度在最远的路径之一儿童。我的定义不那么严格,因此承认更多树木。

也可以不如我的定义那么严格;可以说平衡树是指每个分支上空树的最大路径长度相差不超过两个,或三个或其他常量的树。或者说最大路径长度是最小路径长度的一部分,例如一半或四分之一。

通常没关系。任何树平衡算法的要点是确保在一侧有一百万个节点而另一侧有三个节点的情况下不会结束。 Donal的定义在理论上很好,但在实践中,树木平衡算法会遇到严格的严格程度。性能节省通常不能证明实施成本。你花了很多时间做不必要的树重新排列,以达到一定程度的平衡,在实践中几乎没有什么区别。谁在乎它是否需要四十个树枝才能到达一个百万节点不完美平衡的树中最远的叶子,理论上它在一个完美平衡的树中只需要二十个?关键是它不会花费一百万。从最坏情况下的一百万到最糟糕的情况下,通常都是足够好的;你不必一直走到最佳的情况。

答案 1 :(得分:25)

平衡是一个真正微妙的财产;你认为你知道它是什么,但它很容易出错。特别是,甚至Eric Lippert的(好)答案都没有。那是因为 height 的概念还不够。您需要具有树的最小和最大高度的概念(其中最小高度是从根到叶子的最小步数,并且最大值是......嗯,您得到图片)。鉴于此,我们可以将余额定义为:

  

任何分支的最大高度不超过任何分支最小高度 1 的树。

(这实际上意味着分支本身是平衡的;您可以为最大值和最小值选择相同的分支。)

验证此属性所需的只是一个简单的树遍历,跟踪当前深度。第一次回溯时,会给出基线深度。每次回溯后,您都会将新深度与基线进行比较

  • 如果它等于基线,那么你就继续
  • 如果它不止一个,则树不平衡
  • 如果它是一个关闭,那么你现在知道平衡的范围,所有后续深度(当你即将回溯时)必须是第一个或第二个值。

在代码中:

class Tree {
    Tree left, right;
    static interface Observer {
        public void before();
        public void after();
        public boolean end();
    }
    static boolean traverse(Tree t, Observer o) {
        if (t == null) {
            return o.end();
        } else {
            o.before();
            try {
                if (traverse(left, o))
                    return traverse(right, o);
                return false;
            } finally {
                o.after();
            }
        }
    }
    boolean balanced() {
        final Integer[] heights = new Integer[2];
        return traverse(this, new Observer() {
            int h;
            public void before() { h++; }
            public void after() { h--; }
            public boolean end() {
                if (heights[0] == null) {
                    heights[0] = h;
                } else if (Math.abs(heights[0] - h) > 1) {
                    return false;
                } else if (heights[0] != h) {
                    if (heights[1] == null) {
                        heights[1] = h;
                    } else if (heights[1] != h) {
                        return false;
                    }
                }
                return true;
            }
        });
    }
}

我想你可以在不使用Observer模式的情况下做到这一点,但我觉得这样做更容易理解。


[编辑]:为什么你不能只取每边的高度。考虑这棵树:

        /\
       /  \
      /    \
     /      \_____
    /\      /     \_
   /  \    /      / \
  /\   C  /\     /   \
 /  \    /  \   /\   /\
A    B  D    E F  G H  J

好吧,有点乱,但是根的每一面都是平衡的:C是深度2,ABDE深度为3,FGHJ为深度4.左侧分支的高度为2(请记住,当您遍历分支时,高度会降低),右分支的高度为3.然而整个树平衡,因为CF之间的高度差为2。您需要一个minimax规范(尽管实际算法可能不那么复杂,因为应该只有两个允许的高度)。

答案 2 :(得分:22)

奖金锻炼反应。简单的解决方案。显然,在一个真正的实现中,可以包装这个或者某个东西,以避免要求用户在响应中包含高度。

IsHeightBalanced(tree, out height)
    if (tree is empty)
        height = 0
        return true
    balance = IsHeightBalanced(tree.left, heightleft) and IsHeightBalanced(tree.right, heightright)
    height = max(heightleft, heightright)+1
    return balance and abs(heightleft - heightright) <= 1     

答案 3 :(得分:21)

这仅确定树的顶层是否平衡。也就是说,你可以有一棵树,最左边和最右边有两根长枝,中间没有任何东西,这将是真的。在递回true之前,您需要递归检查root.leftroot.right以查看它们是否内部平衡。

答案 4 :(得分:19)

订单后解决方案,仅遍历树一次。时间复杂度为O(n),空间为O(1),它比自上而下的解决方案更好。我给你一个java版本的实现。

public static <T> boolean isBalanced(TreeNode<T> root){
    return checkBalance(root) != -1;
}

private static <T> int checkBalance(TreeNode<T> node){
    if(node == null) return 0;
    int left = checkBalance(node.getLeft());

    if(left == -1) return -1;

    int right = checkBalance(node.getRight());

    if(right == -1) return -1;

    if(Math.abs(left - right) > 1){
        return -1;
    }else{
        return 1 + Math.max(left, right);
    }
}

答案 5 :(得分:15)

高度平衡二叉树的定义是:

  

二叉树中的高度   每个节点的两个子树永远不会   差异超过1。

所以, 空二叉树总是高度平衡的。
如果出现以下情况,则非空二进制树是高度平衡的:

  1. 它的左子树是高度平衡的。
  2. 它的右子树是高度平衡的。
  3. 高度之差 左和右右子树不大 比1。
  4. 考虑树:

        A
         \ 
          B
         / \
        C   D
    

    如图所示,A的左子树是高度平衡的(因为它是空的),它的右子树也是如此。但由于左子树的高度为0且右子树的高度为2,因此树不是高度平衡的,因为条件3不满足。

    即使左右子树的高度相等,下面的树也不是高度平衡的。您现有的代码将返回true。

           A
         /  \ 
        B    C
       /      \
      D        G
     /          \
    E            H
    

    因此def中的每个这个词非常重要。

    这将有效:

    int height(treeNodePtr root) {
            return (!root) ? 0: 1 + MAX(height(root->left),height(root->right));
    }
    
    bool isHeightBalanced(treeNodePtr root) {
            return (root == NULL) ||
                    (isHeightBalanced(root->left) &&
                    isHeightBalanced(root->right) &&
                    abs(height(root->left) - height(root->right)) <=1);
    }
    

    Ideone Link

答案 6 :(得分:7)

如果二进制树是否平衡,则可以通过级别顺序遍历检查:

private boolean isLeaf(TreeNode root) {
    if (root.left == null && root.right == null)
        return true;
    return false;
}

private boolean isBalanced(TreeNode root) {
    if (root == null)
        return true;
    Vector<TreeNode> queue = new Vector<TreeNode>();
    int level = 1, minLevel = Integer.MAX_VALUE, maxLevel = Integer.MIN_VALUE;
    queue.add(root);
    while (!queue.isEmpty()) {
        int elementCount = queue.size();
        while (elementCount > 0) {
            TreeNode node = queue.remove(0);
            if (isLeaf(node)) {
                if (minLevel > level)
                    minLevel = level;
                if (maxLevel < level)
                    maxLevel = level;
            } else {
                if (node.left != null)
                    queue.add(node.left);
                if (node.right != null)
                    queue.add(node.right);
            }
            elementCount--;
        }
        if (abs(maxLevel - minLevel) > 1) {
            return false;
        }
        level++;
    }

    return true;
}

答案 7 :(得分:7)

这比现实更加复杂。

算法如下:

  1. 设A =最高级别节点的深度
  2. 设B =最低级别节点的深度

  3. 如果abs(A-B)<= 1,那么树是平衡的

答案 8 :(得分:5)

什么平衡手段取决于手头的结构。例如,A B-Tree不能拥有超过根的某个深度的节点,或者更少的节点,所有数据都存在于距离根的固定深度,但如果叶子分布到叶子,它可能会失去平衡但是一个节点不均匀。跳过列表完全没有概念平衡,而是依靠概率来实现良好的性能。 Fibonacci树故意失去平衡,推迟重新平衡以实现优越的渐近性能,以换取偶尔更长时间的更新。 AVL和红黑树将元数据附加到每个节点以获得深度平衡不变量。

所有这些结构和更多都出现在大多数常见编程系统的标准库中(除了python,RAGE!)。实施一两个是很好的编程实践,但它可能不是很好地利用时间来自己进行生产,除非你的问题有一些特殊的性能,不需要任何现成的集合。

答案 9 :(得分:4)

注1:任何子树的高度只计算一次。

注2:如果左子树不平衡,则跳过可能包含百万个元素的右子树的计算。

// return height of tree rooted at "tn" if, and only if, it is a balanced subtree
// else return -1
int maxHeight( TreeNode const * tn ) {
    if( tn ) {
        int const lh = maxHeight( tn->left );
        if( lh == -1 ) return -1;
        int const rh = maxHeight( tn->right );
        if( rh == -1 ) return -1;
        if( abs( lh - rh ) > 1 ) return -1;
        return 1 + max( lh, rh );
    }
    return 0;
}

bool isBalanced( TreeNode const * root ) {
    // Unless the maxHeight is -1, the subtree under "root" is balanced
    return maxHeight( root ) != -1;
}

答案 10 :(得分:3)

如果这是针对您的作业,我建议:

  1. do not reinvent the wheel
  2. use/buy COTS而不是摆弄比特。
  3. 节省您的时间/精力来解决业务问题。

答案 11 :(得分:3)

平衡通常取决于每个方向上最长路径的长度。上面的算法不会为你做那个。

你想要实施什么?周围有自平衡树(AVL /红黑)。 事实上,Java树是平衡的。

答案 12 :(得分:3)

这是一个完整的C#测试解决方案(抱歉,我不是Java开发人员)(只需在控制台应用中复制粘贴)。 我知道平衡的定义各不相同,所以不是每个人都喜欢我的测试结果,但请看一下在递归循环中检查深度/高度并退出第一个不匹配的略微不同的方法,而不保存每个节点上的节点高度/水平/深度(仅在函数调用中维护它。)

using System;
using System.Linq;
using System.Text;

namespace BalancedTree
{
    class Program
    {
        public static void Main()
        {
            //Value Gathering
            Console.WriteLine(RunTreeTests(new[] { 0 }));
            Console.WriteLine(RunTreeTests(new int[] { }));

            Console.WriteLine(RunTreeTests(new[] { 0, 1, 2, 3, 4, -1, -4, -3, -2 }));
            Console.WriteLine(RunTreeTests(null));
            Console.WriteLine(RunTreeTests(new[] { 10, 8, 12, 8, 4, 14, 8, 10 }));
            Console.WriteLine(RunTreeTests(new int[] { 20, 10, 30, 5, 15, 25, 35, 3, 8, 12, 17, 22, 27, 32, 37 }));

            Console.ReadKey();
        }

        static string RunTreeTests(int[] scores)
        {
            if (scores == null || scores.Count() == 0)
            {
                return null;
            }

            var tree = new BinarySearchTree();

            foreach (var score in scores)
            {
                tree.InsertScore(score);
            }

            Console.WriteLine(tree.IsBalanced());

            var sb = tree.GetBreadthWardsTraversedNodes();

            return sb.ToString(0, sb.Length - 1);
        }
    }

    public class Node
    {
        public int Value { get; set; }
        public int Count { get; set; }
        public Node RightChild { get; set; }
        public Node LeftChild { get; set; }
        public Node(int value)
        {
            Value = value;
            Count = 1;
        }

        public override string ToString()
        {
            return Value + ":" + Count;
        }

        public bool IsLeafNode()
        {
            return LeftChild == null && RightChild == null;
        }

        public void AddValue(int value)
        {
            if (value == Value)
            {
                Count++;
            }
            else
            {
                if (value > Value)
                {
                    if (RightChild == null)
                    {
                        RightChild = new Node(value);
                    }
                    else
                    {
                        RightChild.AddValue(value);
                    }
                }
                else
                {
                    if (LeftChild == null)
                    {
                        LeftChild = new Node(value);
                    }
                    else
                    {
                        LeftChild.AddValue(value);
                    }
                }
            }
        }
    }

    public class BinarySearchTree
    {
        public Node Root { get; set; }

        public void InsertScore(int score)
        {
            if (Root == null)
            {
                Root = new Node(score);
            }
            else
            {
                Root.AddValue(score);
            }
        }

        private static int _heightCheck;
        public bool IsBalanced()
        {
            _heightCheck = 0;
            var height = 0;
            if (Root == null) return true;
            var result = CheckHeight(Root, ref height);
            height--;
            return (result && height == 0);
        }

        private static bool CheckHeight(Node node, ref int height)
        {
            height++;
            if (node.LeftChild == null)
            {
                if (node.RightChild != null) return false;
                if (_heightCheck != 0) return _heightCheck == height;
                _heightCheck = height;
                return true;
            }
            if (node.RightChild == null)
            {
                return false;
            }

            var leftCheck = CheckHeight(node.LeftChild, ref height);
            if (!leftCheck) return false;
            height--;
            var rightCheck = CheckHeight(node.RightChild, ref height);
            if (!rightCheck) return false;
            height--;
            return true;
        }


        public StringBuilder GetBreadthWardsTraversedNodes()
        {
            if (Root == null) return null;
            var traversQueue = new StringBuilder();
            traversQueue.Append(Root + ",");
            if (Root.IsLeafNode()) return traversQueue;
            TraversBreadthWards(traversQueue, Root);
            return traversQueue;
        }

        private static void TraversBreadthWards(StringBuilder sb, Node node)
        {
            if (node == null) return;
            sb.Append(node.LeftChild + ",");
            sb.Append(node.RightChild + ",");
            if (node.LeftChild != null && !node.LeftChild.IsLeafNode())
            {
                TraversBreadthWards(sb, node.LeftChild);
            }
            if (node.RightChild != null && !node.RightChild.IsLeafNode())
            {
                TraversBreadthWards(sb, node.RightChild);
            }
        }
    }
}

答案 13 :(得分:3)

public boolean isBalanced(TreeNode root)
{
    return (maxDepth(root) - minDepth(root) <= 1);
}

public int maxDepth(TreeNode root)
{
    if (root == null) return 0;

    return 1 + max(maxDepth(root.left), maxDepth(root.right));
}

public int minDepth (TreeNode root)
{
    if (root == null) return 0;

    return 1 + min(minDepth(root.left), minDepth(root.right));
}

答案 14 :(得分:2)

#include <iostream>
#include <deque>
#include <queue>

struct node
{
    int data;
    node *left;
    node *right;
};

bool isBalanced(node *root)
{
    if ( !root)
    {
        return true;
    }

    std::queue<node *> q1;
    std::queue<int>  q2;
    int level = 0, last_level = -1, node_count = 0;

    q1.push(root);
    q2.push(level);

    while ( !q1.empty() )
    {
        node *current = q1.front();
        level = q2.front();

        q1.pop();
        q2.pop();

        if ( level )
        {
            ++node_count;
        }

                if ( current->left )
                {
                        q1.push(current->left);
                        q2.push(level + 1);
                }

                if ( current->right )
                {
                        q1.push(current->right);
                        q2.push(level + 1);
                }

        if ( level != last_level )
        {
            std::cout << "Check: " << (node_count ? node_count - 1 : 1) << ", Level: " << level << ", Old level: " << last_level << std::endl;
            if ( level && (node_count - 1) != (1 << (level-1)) )
            {
                return false;
            }

            last_level = q2.front();
            if ( level ) node_count = 1;
        }
    }

    return true;
}

int main()
{
    node tree[15];

    tree[0].left  = &tree[1];
    tree[0].right = &tree[2];
    tree[1].left  = &tree[3];
    tree[1].right = &tree[4];
    tree[2].left  = &tree[5];
    tree[2].right = &tree[6];
    tree[3].left  = &tree[7];
    tree[3].right = &tree[8];
    tree[4].left  = &tree[9];   // NULL;
    tree[4].right = &tree[10];  // NULL;
    tree[5].left  = &tree[11];  // NULL;
    tree[5].right = &tree[12];  // NULL;
    tree[6].left  = &tree[13];
    tree[6].right = &tree[14];
    tree[7].left  = &tree[11];
    tree[7].right = &tree[12];
    tree[8].left  = NULL;
    tree[8].right = &tree[10];
    tree[9].left  = NULL;
    tree[9].right = &tree[10];
    tree[10].left = NULL;
    tree[10].right= NULL;
    tree[11].left = NULL;
    tree[11].right= NULL;
    tree[12].left = NULL;
    tree[12].right= NULL;
    tree[13].left = NULL;
    tree[13].right= NULL;
    tree[14].left = NULL;
    tree[14].right= NULL;

    std::cout << "Result: " << isBalanced(tree) << std::endl;

    return 0;
}

答案 15 :(得分:1)

boolean isBalanced(Node root) {
    if (longestPath(root) - shortestPath(root) > 1)
        return false;
    else
        return true;
}


int longestPath(Node root) {
    if (root == null);
        return 0;
    else {
        int leftPathLength = longestPath(root.left);
        int rightPathLength = longestPath(root.right);
        if (leftPathLength >= rightPathLength)
            return leftPathLength + 1;
        else
            return rightPathLength + 1;
    }
}

int shortestPath(Node root) {
    if (root == null);
        return 0;
    else {
        int leftPathLength = shortestPath(root.left);
        int rightPathLength = shortestPath(root.right);
        if (leftPathLength <= rightPathLength)
            return leftPathLength + 1;
        else
            return rightPathLength + 1;
    }
}

答案 16 :(得分:1)

RE:@lucky使用BFS进行级别顺序遍历的解决方案。

我们遍历树并保留对vars min / max-level的引用,该级别描述了节点是叶的最小级别。

我认为@lucky解决方案需要修改。正如@codaddict所建议的那样,我们必须检查左或右子级是否为空(而不是全部),而不是检查节点是否为叶。否则,算法将认为这是有效的平衡树:

     1
    / \
   2   4
    \   \
     3   1

在Python中:

def is_bal(root):
    if root is None:
        return True

    import queue

    Q = queue.Queue()
    Q.put(root)

    level = 0
    min_level, max_level = sys.maxsize, sys.minsize

    while not Q.empty():
        level_size = Q.qsize()

        for i in range(level_size):
            node = Q.get()

            if not node.left or node.right:
                min_level, max_level = min(min_level, level), max(max_level, level)

            if node.left:
                Q.put(node.left)
            if node.right:
                Q.put(node.right)

        level += 1

        if abs(max_level - min_level) > 1:
            return False

    return True

此解决方案应满足初始问题中提供的所有规定,并且要在O(n)时间和O(n)空间中运行。内存溢出将被定向到堆,而不是吹散递归调用栈。

或者,我们最初可以遍历树以迭代方式为每个根子树计算+缓存最大高度。然后,在另一次迭代运行中,检查每个根的左右子树的缓存高度是否相差不超过一个。这也可以在O(n)时间和O(n)空间中运行,但是要反复进行,以免引起堆栈溢出。

答案 17 :(得分:1)

嗯,你需要一种方法来确定左右高度,如果左右平衡。

我只是return height(node->left) == height(node->right);

关于编写height函数,请阅读: Understanding recursion

答案 18 :(得分:1)

这是一个基于通用深度优先遍历的版本。应该比其他正确答案更快并处理所有提到的“挑战”。对于风格道歉,我真的不懂Java。

如果max和min都设置了并且差异大于1,你仍然可以通过提早返回来加快速度。

public boolean isBalanced( Node root ) {
    int curDepth = 0, maxLeaf = 0, minLeaf = INT_MAX;
    if ( root == null ) return true;
    while ( root != null ) {
        if ( root.left == null || root.right == null ) {
            maxLeaf = max( maxLeaf, curDepth );
            minLeaf = min( minLeaf, curDepth );
        }
        if ( root.left != null ) {
            curDepth += 1;
            root = root.left;
        } else {
            Node last = root;
            while ( root != null
             && ( root.right == null || root.right == last ) ) {
                curDepth -= 1;
                last = root;
                root = root.parent;
            }
            if ( root != null ) {
                curDepth += 1;
                root = root.right;
            }
        }
    }
    return ( maxLeaf - minLeaf <= 1 );
}

答案 19 :(得分:1)

你正在谈论什么样的树?那里有self-balancing棵树。检查他们的算法,确定他们是否需要重新排序树以保持平衡。

答案 20 :(得分:0)

空树是高度平衡的。在以下情况下,非空二进制树T是平衡的:

1)T的左子树是平衡的

2)T的右子树是平衡的

3)左子树和右子树的高度之差不超过1。

/* program to check if a tree is height-balanced or not */
#include<stdio.h>
#include<stdlib.h>
#define bool int

/* A binary tree node has data, pointer to left child
   and a pointer to right child */
struct node
{
  int data;
  struct node* left;
  struct node* right;
};

/* The function returns true if root is balanced else false
   The second parameter is to store the height of tree.  
   Initially, we need to pass a pointer to a location with value 
   as 0. We can also write a wrapper over this function */
bool isBalanced(struct node *root, int* height)
{
  /* lh --> Height of left subtree 
     rh --> Height of right subtree */   
  int lh = 0, rh = 0;  

  /* l will be true if left subtree is balanced 
    and r will be true if right subtree is balanced */
  int l = 0, r = 0;

  if(root == NULL)
  {
    *height = 0;
     return 1;
  }

  /* Get the heights of left and right subtrees in lh and rh 
    And store the returned values in l and r */   
  l = isBalanced(root->left, &lh);
  r = isBalanced(root->right,&rh);

  /* Height of current node is max of heights of left and 
     right subtrees plus 1*/   
  *height = (lh > rh? lh: rh) + 1;

  /* If difference between heights of left and right 
     subtrees is more than 2 then this node is not balanced
     so return 0 */
  if((lh - rh >= 2) || (rh - lh >= 2))
    return 0;

  /* If this node is balanced and left and right subtrees 
    are balanced then return true */
  else return l&&r;
}


/* UTILITY FUNCTIONS TO TEST isBalanced() FUNCTION */

/* Helper function that allocates a new node with the
   given data and NULL left and right pointers. */
struct node* newNode(int data)
{
    struct node* node = (struct node*)
                                malloc(sizeof(struct node));
    node->data = data;
    node->left = NULL;
    node->right = NULL;

    return(node);
}

int main()
{
  int height = 0;

  /* Constructed binary tree is
             1
           /   \
         2      3
       /  \    /
     4     5  6
    /
   7
  */   
  struct node *root = newNode(1);  
  root->left = newNode(2);
  root->right = newNode(3);
  root->left->left = newNode(4);
  root->left->right = newNode(5);
  root->right->left = newNode(6);
  root->left->left->left = newNode(7);

  if(isBalanced(root, &height))
    printf("Tree is balanced");
  else
    printf("Tree is not balanced");    

  getchar();
  return 0;
}

时间复杂度:O(n)

答案 21 :(得分:0)

为了在巨大的树上获得更好的性能,你可以节省每个节点的高度,这是一个权衡空间与性能:

class Node {
    Node left;
    Node right;
    int value;
    int height;
}

实施添加和删除相同的示例

void addNode(Node root,int v)
{    int height =0;
     while(root != null)
     {
         // Since we are adding new node so the height 
         // will increase by one in each node we will pass by
         root.height += 1;
         height++;
         else if(v > root.value){
            root = root.left();
            }
         else{
         root = root.right();
         }

     }

         height++;
         Node n = new Node(v , height);
         root = n;         
}
int treeMaxHeight(Node root)
{
 return Math.Max(root.left.height,root.right.height);
}

int treeMinHeight(Node root)
{
 return Math.Min(root.left.height,root.right.height);

}

Boolean isNodeBlanced(Node root)
{
   if (treeMaxHeight(root) - treeMinHeight(root) > 2)
       return false;

  return true;
}

Boolean isTreeBlanced (Node root)
{
    if(root == null || isTreeBalanced(root.left) && isTreeBalanced(root.right) && isNodeBlanced(root))
    return true;

  return false;

}

答案 22 :(得分:0)

public int height(Node node){
    if(node==null)return 0;
    else{
        int l=height(node.leftChild);
        int r=height(node.rightChild);
       return(l>r?l+1:r+1);

}}
public boolean balanced(Node n){

    int l= height(n.leftChild);
    int r= height(n.rightChild);

    System.out.println(l + " " +r);
    if(Math.abs(l-r)>1)
        return false;
    else 
        return true;
    }

答案 23 :(得分:0)

以下是我为埃里克的奖金练习所尝试的内容。 我尝试放松我的递归循环,并在找到不平衡的子树后立即返回。

int heightBalanced(node *root){
    int i = 1;
    heightBalancedRecursive(root, &i);
    return i; 
} 

int heightBalancedRecursive(node *root, int *i){

    int lb = 0, rb = 0;

    if(!root || ! *i)  // if node is null or a subtree is not height balanced
           return 0;  

    lb = heightBalancedRecursive(root -> left,i);

    if (!*i)         // subtree is not balanced. Skip traversing the tree anymore
        return 0;

    rb = heightBalancedRecursive(root -> right,i)

    if (abs(lb - rb) > 1)  // not balanced. Make i zero.
        *i = 0;

    return ( lb > rb ? lb +1 : rb + 1); // return the current height of the subtree
}

答案 24 :(得分:0)

class Node {
    int data;
    Node left;
    Node right;

    // assign variable with constructor
    public Node(int data) {
        this.data = data;
    }
}

public class BinaryTree {

    Node root;

    // get max depth
    public static int maxDepth(Node node) {
        if (node == null)
            return 0;

        return 1 + Math.max(maxDepth(node.left), maxDepth(node.right));
    }

    // get min depth
    public static int minDepth(Node node) {
        if (node == null)
            return 0;

        return 1 + Math.min(minDepth(node.left), minDepth(node.right));
    }

    // return max-min<=1 to check if tree balanced
    public boolean isBalanced(Node node) {

        if (Math.abs(maxDepth(node) - minDepth(node)) <= 1)
            return true;

        return false;
    }

    public static void main(String... strings) {
        BinaryTree tree = new BinaryTree();
        tree.root = new Node(1);
        tree.root.left = new Node(2);
        tree.root.right = new Node(3);


        if (tree.isBalanced(tree.root))
            System.out.println("Tree is balanced");
        else
            System.out.println("Tree is not balanced");
    }
}

答案 25 :(得分:-1)

    static boolean isBalanced(Node root) {
    //check in the depth of left and right subtree
    int diff = depth(root.getLeft()) - depth(root.getRight());
    if (diff < 0) {
        diff = diff * -1;
    }
    if (diff > 1) {
        return false;
    }
    //go to child nodes
    else {
        if (root.getLeft() == null && root.getRight() == null) {
            return true;
        } else if (root.getLeft() == null) {
            if (depth(root.getRight()) > 1) {
                return false;
            } else {
                return true;
            }
        } else if (root.getRight() == null) {
            if (depth(root.getLeft()) > 1) {
                return false;
            } else {
                return true;
            }
        } else if (root.getLeft() != null && root.getRight() != null && isBalanced(root.getLeft()) && isBalanced(root.getRight())) {
            return true;
        } else {
            return false;
        }
    }
}

答案 26 :(得分:-2)

这不会起作用吗?

return ( ( Math.abs( size( root.left ) - size( root.right ) ) < 2 );

任何不平衡的树都会​​失败。