题目:输入一棵二叉树的根结点,判断该树是不是平衡二叉树。如果某二叉树中任意结点的左右子树的深度相差不超过1,那么它就是一棵平衡二叉树。
package offer;
/**
* 判断是否是平衡二叉树
*
*/
public class IsBalanced {
public static void main(String[] args){
int[] pre = {1,2,4,5,7,3,6};
int[] inorder = {4,2,7,5,1,3,6};
BinaryTreeNode root = RebuildBinaryTree.rebuildBinaryTree(pre, inorder);
System.out.println(isBalanced(root,new Depth()));
//没有右子树
int[] pre2 = {1,2,3,4,5};
int[] in2 = {5,4,3,2,1};
BinaryTreeNode root2 = RebuildBinaryTree.rebuildBinaryTree(pre2, in2);
System.out.println(isBalanced(root2,new Depth()));
//没有左子树
int[] pre3 = {1,2,3,4,5};
int[] in3 = {1,2,3,4,5};
BinaryTreeNode root3 = RebuildBinaryTree.rebuildBinaryTree(pre3, in3);
System.out.println(isBalanced(root3,new Depth()));
//只有一个结点
BinaryTreeNode root5 = new BinaryTreeNode(1);
System.out.println(isBalanced(root5,new Depth()));
root5 = null;
System.out.println(isBalanced(root5,new Depth()));
}
/*
* 后序遍历的方式遍历二叉树的每一个结点,在遍历到一个结点之前就已经遍历了它的左右子树。
* 只要在遍历每个结点的时候记录它的深度,就可以一边遍历一边判断每个结点是不是平衡的。
*/
public static boolean isBalanced(BinaryTreeNode node, Depth aux) {
if (node == null) {
aux.depth = 0;
return true;
}
Depth left = new Depth();
Depth right = new Depth();
// get leftTreeDepth and rightTreeDepth of a node.
// If the 'diff' is bigger than 1,return false;true otherwise
if (isBalanced(node.left, left) && isBalanced(node.right, right)) {
int leftDepth = left.depth;
int rightDepth = right.depth;
int diff = leftDepth - rightDepth;
if (diff == 1 || diff == -1 || diff == 0) {
aux.depth = leftDepth > rightDepth ? leftDepth + 1 : rightDepth + 1;
return true;
}
}
return false;
}
public static class Depth {
private int depth;
}
/**
* 第二种方法,在遍历二叉树每个结点的时候,调用函数TreeDepth得到它的左右子树的深度。
* 这种方法一个结点会被重复遍历。
* @param root
* @return
*/
public static boolean isBalanced2(BinaryTreeNode root){
if(root==null)
return true;
int left = TreeDepth.treeDepth(root.left);
int right = TreeDepth.treeDepth(root.right);
int diff = left-right;
if(diff>1 || diff<-1)
return false;
return isBalanced2(root.left)&&isBalanced2(root.right);
}
}