
分析:
为了避免树的高度增长过快,降低二叉排序树的性能,我们规定在插入和删除二叉树的结点时,要保证任意结点
的左、右子树高度差的绝对值不能超过1,将这样的二叉树称为平衡二叉树。
平衡二叉树可定义为它或者是一棵空树,或者是具有以下性质的二叉树:它的左子树和右子树都是平衡二叉树,且
左子树和右子树的高度差的绝对值不超过1。
先序遍历思想:
public boolean IsBalanced_Solution(TreeNode root)
{
//judge_AVL(root, balance, h);
//return balance;
// 如果二叉树为空,是AVL
if (root == null)
{
return true;
}
// 如果左右子树高度差大于1,不是AVL
if (Math.abs(getHeight(root.left) - getHeight(root.right)) > 1)
{
return false;
}
return IsBalanced_Solution(root.left) && IsBalanced_Solution(root.right);
// 等价于
/*
return (Math.abs(getHeight(root.left) - getHeight(root.right)) <= 1) &&
IsBalanced_Solution(root.left) && IsBalanced_Solution(root.right);
*/
}
// 递归求解二叉树的某个结点的高度
public int getHeight(TreeNode root)
{
if (root == null)
return 0;
return Math.max(getHeight(root.left), getHeight(root.right)) + 1;
}
这种做法的缺点是在判断上层结点的时候,会多次重复遍历下层结点,增加了不必要的开销。如果改为从
下往上遍历,如果子树是平衡二叉树,则返回子树的高度;如果发现子树不是平衡二叉树,则直接停止遍历,这
样至多只对每个结点访问一次。
public boolean IsBalanced_Solution(TreeNode root)
{
return getDepth(root) != -1;
}
private int getDepth(TreeNode root)
{
if (root == null)
return 0;
int left = getDepth(root.left); // 计算左子树高度
if (left == -1) // 只要左子树不平衡,就不再判断右子树
return -1;
int right = getDepth(root.right); // 计算右子树高度
if (right == -1) // 右子树不平衡,返回-1
return -1;
return Math.abs(left - right) > 1 ? -1 : 1 + Math.max(left, right);
}
相比较上面一种解法,下面这种解法,就得需要遍历完所有的结点一次,才知道是否是AVL。
private boolean isBalanced = true;
public boolean IsBalanced_Solution(TreeNode root)
{
getDepth(root);
return isBalanced;
}
public int getDepth(TreeNode root)
{
// 子树为空
if (root == null)
return 0;
// 得到左子树的高度
int left = getDepth(root.left);
// 得到右子树的高度
int right = getDepth(root.right);
// 左右子树高度差大于1
if (Math.abs(left - right) > 1)
isBalanced = false;
// 结点的高度为最高子树高度+1
return right > left ? right + 1 : left + 1;
}
6519

被折叠的 条评论
为什么被折叠?



