题意描述:
给定一个棵树的根节点,判断该树是否为平衡二叉树?
什么是平衡二叉树?
平衡二叉树(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