題意描述:
給定一個棵樹的根節點,判斷該樹是否爲平衡二叉樹?
什麼是平衡二叉樹?
平衡二叉樹(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