判断一颗树是否为平衡二叉树

题意描述:

给定一个棵树的根节点,判断该树是否为平衡二叉树?

什么是平衡二叉树?

平衡二叉树(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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值