Java检查二叉树是否平衡

时间:2015-01-20 02:22:04

标签: java iteration binary-tree binary-search-tree breadth-first-search

这是“破解编码面试”的问题:

  

实现一个函数来检查树是否平衡。出于此问题的目的,将平衡树定义为树,使得两个叶节点与根的距离不超过一个。

这本书只提供递归解决方案。我想出了一个使用BFS的迭代解决方案,只是想分享它。我干了它,但想确保我没有犯错。我还想看看其他人怎么认为他们可以改进它。

谢谢!

2 个答案:

答案 0 :(得分:1)

class Node
{
int data;
LinkedList<Node> children;
}

public static boolean isBalanced(Node root)
{
LinkedList<Node> queue = new LinkedList<Node>();
queue.offer(root);

int currentLevel = -1, toNextLevel = 0, toNextLevelTemp = 1;

int minLevel = Integer.MAX_VALUE, maxLevel = Integer.MIN_VALUE;

while(!queue.isEmpty())
{
    if(toNextLevel == 0)
    {
        currentLevel++;
        toNextLevel = toNextLevelTemp;
        toNextLevelTemp = 0;
    }

    Node temp = queue.poll();
    toNextLevel--;

    //if temp is a leaf, record its depth
    if(temp.children.size() == 0)   
    {
        if(currentLevel < minLevel)
            minLevel = currentLevel;

        if(currentLevel > maxLevel)
            maxLevel = currentLevel;
    }

    //do whatever with temp
    for(Node child: temp.children)
    {
        queue.add(child);
        toNextLevelTemp++;
    }
}

//if difference between minLevel and maxLevel is more than 1
if(maxLevel - minLevel > 1)
    return false;

return true;
}

答案 1 :(得分:1)

花了我比预期更长的时间,但这个解决方案有效,随意让我的代码变得更漂亮,在我开始工作后我做了最小的修饰

/* Returns true if binary tree with root as root is height-balanced */
    boolean isBalanced(Node root) {
        if(root == null) return false;

        Deque<Integer> heights = new LinkedList<>();
        Deque<Node> trail = new LinkedList<>();
        trail.push(root);

        Node prev = root; //set to root not null to not confuse when root is misisng children

        while(!trail.isEmpty()) {
            Node curr = trail.peek(); //get the next node to process, peek because we need to maintain trail until we return

            //if we just returned from left child
            if (curr.left == prev) {
                if(curr.right != null) trail.push(curr.right); //if we can go right go
                else {
                    heights.push(-1); //otherwise right height is -1 does not exist and combine heights
                    if(!combineHeights(heights)) return false;
                    trail.pop(); //back to parent
                }
            }
            //if we just returned from right child
            else if (curr.right == prev) {
                if(!combineHeights(heights)) return false;
                trail.pop(); //up to parent
            }
            //this came from a parent, first thing is to visit the left child, or right if no left
            else {
                if(curr.left != null) trail.push(curr.left);
                else {
                    if (curr.right != null) {
                        heights.push(-1); //no left so when we combine this node left is 0
                        trail.push(curr.right); //since we never go left above logic does not go right, so we must here
                    }
                    else { //no children set height to 1
                        heights.push(0);
                        trail.pop(); //back to parent
                    }
                }
            }

            prev = curr;
        }

        return true;
    }

    //pop both previous heights and make sure they are balanced, if not return false, if so return true and push the greater plus 1
    private boolean combineHeights(Deque<Integer> heights) {
        int rightHeight = heights.pop();
        int leftHeight = heights.pop();

        if(Math.abs(leftHeight - rightHeight) > 1) return false;
        else heights.push(Math.max(leftHeight, rightHeight) + 1);
        return true;
    }