Java проверяет, сбалансировано ли двоичное дерево

1

Это вопрос от "Cracking the Coding Interview":

Внедрите функцию, чтобы проверить, сбалансировано ли дерево. Для целей этого вопроса сбалансированное дерево определяется как дерево, так что ни один из двух листовых узлов не отличается от корня более чем одним.

Книга дает только рекурсивное решение. Я придумал итерационное решение с использованием BFS и просто хотел поделиться им. Я сделал это, но хотел убедиться, что не ошибся. Я также хотел бы посмотреть, как другие люди думают, что они смогут улучшить его.

Благодарю!

Теги:
breadth-first-search
binary-search-tree
iteration
binary-tree

2 ответа

0

взял меня дольше, чем я ожидал, но это решение работает, не стесняйтесь сделать мой код красивее, после того как я получил его работу, я сделал минимальное касание

/* 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;
    }
0
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;
}
  • 0
    Переменная "toNextLevel" отслеживает, сколько узлов до следующего уровня. «toNextLevelTemp» подсчитывает количество узлов, добавляемых в очередь, пока они находятся на текущем уровне, и присваивает свое значение «toNextLevel» при увеличении уровня.
  • 0
    Я не думаю, что это сработает, подумайте, если у вас нет ребенка на одной стороне, он будет игнорироваться, это учитывает только листья, если один из дочерних узлов равен нулю, то другому не разрешается иметь детей в сбалансированное дерево, плохо с ним связываться и посмотреть, смогу ли я найти интуитивно понятный способ интегрировать это в это решение

Ещё вопросы

Сообщество Overcoder
Наверх
Меню