判斷一顆樹是否爲平衡二叉樹

題意描述:

給定一個棵樹的根節點,判斷該樹是否爲平衡二叉樹?

什麼是平衡二叉樹?

平衡二叉樹(AVL, Self-balancing binary search tree)是一棵所有節點的左右子樹深度差不超過1的二叉搜索樹。
這表明AVL首先是一個二叉搜索樹,在節點的數值上有約束,同時對樹形有嚴格要求,具有以下性質:一棵空樹或它的左右兩個子樹的高度差的絕對值不超過1,並且左右兩個子樹都是一棵平衡二叉樹。

思路:

根據定義,AVL樹是一棵二叉搜索樹(root.left.val <= root.val <= root.right.val),同時每一個節點的左右子樹高度差不超過1.
於是,可以採用後序遍歷,從底向上遍歷,判斷每一個節點是否滿足上述兩個條件:
1. root.left.val <= root.val <= root.right.val;
2. Math.abs(depth(root.left)-depth(root.right)) <= 1;
注意空樹是AVL樹。

具體可以定義一個布爾型的全局變量flag,後序遍歷的過程中,只要有一個節點不滿足上述兩個條件,則flag == false。
只要flag爲false則表明該樹不是AVL樹。這樣做的好處是,從底向上遇到不滿足條件的節點時可以提前終止遍歷,而不用遍歷整棵樹。
最壞情況時間複雜度爲O(N),N爲樹的節點數;
空間複雜度O(1)。

代碼實現如下:

public class isAVL {

    private static boolean flag = true;

    public static void main(String argus[]) {
        TreeNode node1 = new TreeNode(1), node2 = new TreeNode(2),
                node3 = new TreeNode(3), node4 = new TreeNode(4),
                node5 = new TreeNode(5), node6 = new TreeNode(6),
                node7 = new TreeNode(7), node8 = new TreeNode(8);
        //下面這棵樹是AVL樹,輸出爲true
/*        node3.left = node2;
        node3.right = node5;
        node2.left = node1;
        node5.left = node4;
        node5.right = node6;*/
        //下面這棵樹不是AVL樹,不滿足條件2。
/*        node3.left = node2;
        node3.right = node4;
        node2.left = node1;
        node4.left = node5;
        node4.right = node6;
        node6.right = node7;
        node7.right = node8;*/

        //下面這棵樹不是AVL樹。節點node4不滿足條件1。
        node3.left = node2;
        node3.right = node4;
        node2.left = node1;
        node4.left = node5;
        node4.right = node6;
        judge(node3);

        System.out.println(flag);
    }

    private static int judge(TreeNode root) {
        if (flag) {
            if (root != null) {
                if (root.left != null && root.left.val > root.val)
                    flag = false;
                if (flag && root.right != null && root.right.val < root.val)
                    flag = false;
                int left = judge(root.left), right = judge(root.right);
                if (flag && Math.abs(left - right) > 1)
                    flag = false;
                return Math.max(left, right) + 1;
            }
            return 0;
        }
        return 0;
    }
}

輸出

false
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章