二叉树的基本算法2

162 阅读3分钟

1.判断二叉树是否是完全二叉树

  • 完全二叉树: 对于一个树高为h的二叉树,如果其第0层至第h-1层的节点都满。如果最下面一层节点不满,则所有的节点在左边的连续排列,空位都在右边。这样的二叉树就是一棵完全二叉树。
//判断是否为完全二叉树
public static boolean isCBT1(Node head) {
    if (head == null) {
        return null;
    }
    LinkedList<Node> queue = new LinkedList<>();
    //是否遇到过左右两个孩子不全的节点
    boolean left = false;
    Node l = null;
    Node r = null;
    queue.add(head);
    while (!queue.isEmpty()) {
        head = queue.poll();
        l = head.left;
        r = head.right;
        //// 如果遇到了不双全的节点之后,又发现当前节点不是叶节点
        if (leaf && (l != null || r != null)) ||(l == null && r != null)) {
            return false;
        }
        if (l != null) {
            queue.add(l);
        }
        if (r != null) {
            queue.add(r);
        }
        if (l == null || r == null) {
            leaf = true;
        }
    }
    return true;
}

2.返回是否为平衡二叉树

条件一:它必须是二叉查找树。

条件二:每个节点的左子树和右子树的高度差至多为1。

image.png

思路:需要其为平衡数且高度差为1

public static boolean isBalance(NOde head) {
    return process(head).isBalanced;
}
​
public static class Info {
    public boolean isBalanced;
    public int height;
    
    public Info(boolean i, int h) {
        isBalanced = i;
        height = h;
    }
    public static Info process(Node x) {
        if (x == null) {
            return new Info(true, 0);
        }
        Info leftInfo = process(x.left);
        Info rightInfo = process(x.right);
        int height = Math.max(leftInfo.height, rightInfo.height) + 1;
        boolean isBalanced = true;
        if (!leftInfo.isBalanced) {
            isBalanced = false;
        }
        if (!rightInfo.isBalanced) {
            isBalanced = false;
        }
        if (Math.abs(leftInfo.height - rightInfo.height) > 1) {
            isBalanced = false;
        }
        return new Info (isBalanced, height);
    }
}

3.判断二叉树是否是搜索二叉树

若它的左子树不空,则左子树上所有结点的值均小于它的 根结点 的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值

image.png

代码解析:

public static class Node {
    public int value;
    public Node left;
    public Node right;
​
    public Node(int data) {
        this.value = data;
    }
}
​
public static boolean isBST2(Node head) {
    if (head == null) {
        return true;
    }
    return process(head).isBST;
}
​
public static Info process(Node x) {
    if (x == null) {return null;}
    Info leftInfo = process(x.left);
    Info rightInfo = process(x.right);
    int max = x.value;
    if (leftInfo != null) {
        max = Math.max(max, leftInfo.max);
    }
    if (rightInfo != null) {
        max = Math.max(max, rightInfo.max);
    }
    int min = x.value;
    if (leftInfo != null) {
        min = Math.min(min, leftInfo.min);
    }
    if (rightInfo != null) {
        min = Math.min(min, rightInfo.min);
    }
    boolean isBST = true;
    if (leftInfo != null && !leftInfo.isBST) {
        isBST = false;
    }
    if (rightInfo != null && !rightInfo.isBST) {
        isBST = false;
    }
    if (leftInfo != null && leftInfo.max >= x.value) {
        isBST = false;
    }
    if (rightInfo != null && rightInfo.min <= x.value) {
        isBST = false;
    }
    return new Info(isBST, max, min);
}

4.给定一棵二叉树的头节点head,任何两个节点之间都存在距离,返回整棵二叉树的最大距离

image.png

image.png

public static int maxDistance2(Node head) {
    return process(head).maxDistance;
}
​
public static class Info {
    public int maxDistance;//最大距离
    public int height;
    
    public Info (int m, int h) {
        maxDistance = ml
        height = h;
    }
}
​
public static Info process(Node x) {
    if (x == null) {
        return new Info (0, 0);
    }
    Info leftInfo = process(x.left);
    Info rightInfo = process(x.right);
    int height = Math.max(leftInfo.height, rightInfo.height) + 1;
    int p1 = leftInfo.maxDistance;//x左树的最大距离
    int p2 = rightInfo.maxDistance;//x右树的最大距离
    int p3 = leftInfo.height + rightInfo.height + 1;//左树的最大高度与右树的最大高度+1
    int maxDistance = Math.max(Math.max(p1, p2), p3);//得到最大的左到右的最大距离
    return new Info(maxDistance, height);
}
​

5.判断是否为满二叉树

// 收集子树是否是满二叉树
// 收集子树的高度
// 左树满 && 右树满 && 左右树高度一样 -> 整棵树是满的
public static boolean isFull2(Node head) {
    if (head == null) {
        return true;
    }
    return process2(head).isFull;
}
​
public static class Info2 {
    public boolean isFull;
    public int height;
​
    public Info2(boolean f, int h) {
        isFull = f;
        height = h;
    }
}
​
public static Info2 process2(Node h) {
    if (h == null) {
        return new Info2(true, 0);
    }
    Info2 leftInfo = process2(h.left);
    Info2 rightInfo = process2(h.right);
    //左边的最大高度与右边的最大高度是否一致
    boolean isFull = leftInfo.isFull && rightInfo.isFull && leftInfo.height == rightInfo.height;
    //返回左右最大高度的值
    int height = Math.max(leftInfo.height, rightInfo.height) + 1;
    return new Info2(isFull, height);
}

6.找到最大的子树是搜索二叉树

(1)解法:找到最大子树的搜索二叉树可以左边为搜索二叉树 或者右边搜索二叉树

因此这里如果有左右的搜索二叉树找到其

image.png

子树的定义:从节点开始的节点数

image.png

public static int maxSubBSTSize2(Node head) {
    if (head == null) {
        return 0;
    }
    return process(head).maxBSTSubtreeSize;
}
​
public static class Info {
    public int maxBSTSubtreeSize;
    public int allSize;
    public int max;
    public int min;
    
    public Info(int m, int a, int ma, int mi) {
        maxBSTSubtreeSize = m;
        allSize = a;
        max = ma;
        min = mi;
    }
}
​
public static Info process(Node x) {
    if (x == null) {
        return null;
    }
    Info leftInfo = process(x.left);
    Info rightInfo = process(x.right);
    int max = x.value;
    int min = x.value;
    int allSize = 1;
    if (leftInfo != null) {
        max = Math.max(leftInfo.max, max);
        min = Math.min(leftInfo.min, min);
        allSize += leftInfo.allSize;
    }
    if (rigthInfo != null) {
        max = Math.max(rightInfo.max, max);
        min = Math.min(rightInfo.min, min);
        allSize += rightInfo.allSize;
    }
    int p1 = -1;
    if (leftInfo != null) {
        p1 = leftInfo.maxBSTSubtreeSize;
    }
    int p2 = -1;
    if (rightInfo != null) {
        p2 = rightInfo.maxBSTSubtreeSize;
    }
    int p3 = -1;
    boolean leftBST = leftInfo == null ? true:(leftInfo.maxBSTSubtreeSize == leftInfo.allSize);
    boolean rightBST = rightInfo == null ? true:(rightInfo.maxBSTSubtreeSize == rightInfo.allSize);
    if (leftBST && rightBST) {
        boolean leftMaxLessX = leftInfo == null ? true : (leftInfo.max < x.value);
        boolean rightMinMoreX = rightInfo == null ? true : (x.value < rightInfo.min);
        if (leftMaxLessX && rightMinMoreX) {
            int leftSize = leftInfo == null ? 0 : leftInfo.allSize;
            int rightSize = rightInfo == null ? 0 : rightInfo.allSize;
            p3 = leftSize + rightSize + 1;
        }
    }
    return new Info(Math.max(p1, Math.max(p2, p3)), allSize, max, min);
}

\