实现一个函数,检查二叉树是否平衡。

二叉树平衡的定义以下:任意一个结点,其两颗子树的高度差不超过1javascript

递归访问每一个整棵树,计算每一个结点子树的高度java

 

[java] view plain copynode

 

  1. public class BTreeBalanced {  
  2.     static class TreeNode {  
  3.         int data;  
  4.         static TreeNode left;  
  5.         static TreeNode right;  
  6.     }  
  7.     public static boolean isBalanced(TreeNode root) {  
  8.         if (null == root) return true;  
  9.         int heightDiff = getHeight(root.left) - getHeight(root.right);  
  10.         if ( Math.abs(heightDiff)  > 1 ) {  
  11.             return false;  
  12.         }  
  13.         else {  
  14.             return ( isBalanced(TreeNode.left) && isBalanced(TreeNode.right) );  
  15.         }  
  16.     }  
  17.     public static int getHeight(TreeNode root) {  
  18.         if (null == root) return 0;  
  19.         return Math.max( getHeight(root.left), getHeight(root.right) + 1 );  
  20.     }  
  21. }  


但这样作的效率不高,getHeight()会被反复调用计算同一个结点的高度,时间复杂度为O(N logN)app

 

getHeight()其实不只能够检查高度,还能检查树是否平衡,只要将判断左右子树高度差是否大于一放进getHeight()就能够了,下面用checkHeight()来表示这一段代码。spa

这样作的好处是时间复杂度下降了,为O(N),空间复杂度为O(H),H为树的高度.net

 

[java] view plain copyblog

 

  1. public static int checkHeight(TreeNode root) {  
  2.         if (null == root) return 0;  
  3.         int leftHeight = checkHeight(root.left);  
  4.         if ( leftHeight == -1 ) {  
  5.             return -1; //unbalanced  
  6.         }  
  7.           
  8.         int rightHeight = checHeight(root.right);  
  9.         if ( rightHeight == -1 ) {  
  10.             return -1; //unbalanced  
  11.         }  
  12.           
  13.         int heightDiff = leftHeight - rightHeight;  
  14.         if (Math.abs(heightDiff) > 1) {  
  15.             return -1; // unbalanced  
  16.         }  
  17.         else {  
  18.             return Math.max( rightHeight, rightHeight + 1 );  
  19.         }  
  20.     }  
  21.     public static boolean isBalanced2(TreeNode root) {  
  22.         if(checkHeight(root) == -1) {  
  23.             return false;  
  24.         }  
  25.         else {  
  26.             return true;  
  27.         }  
  28.     } 

或者:递归

  1. int getHeight(Node node){  
  2.    if(node==null){  
  3.       return 0;  
  4.    }  
  5.    int heigth = 1;  
  6.    if(node.left!=null){  
  7.       height = 1+getHeight(node.left);  
  8.   }  
  9.    if(node.rigth!=null){  
  10.       int h = 1+getHeight(node.right);  
  11.       height = height>h?height:h;  
  12.    }  
  13.   return height;  
  14. }  
  15.   
  16. boolean isBalance(Node node){  
  17.    if(node==null){  
  18.      return true;  
  19.    }  
  20.    int left = getHeight(node.left);  
  21.    int right = getHeight(node.right);  
  22.    int diff = left - right;  
  23.     if(diff > 1 || diff < -1)  
  24.         return false;  
  25.    return isBalance(node.left)&&isBalance(node.right);  
  26. }  



咱们用后序遍历的方式遍历二叉树的每个结点,在遍历到一个结点以前咱们已经遍历了它的左右子树。只要在遍历每一个结点的时候记录它的深度(某一结点的深度等于它到叶节点的路径的长度),咱们就能够一边遍历一边判断每一个结点是否是平衡的
 ip

Java代码get

 收藏代码

  1. boolean isBalance(Node node,Depth d){  
  2.    if(node==null){  
  3.       d.height=0;  
  4.       return true;  
  5.    }  
  6.    Depth right=new Depth();  
  7.    depth left = new Depth();  
  8.    if(isBalance(node.left,left)&&isBalance(node.right,right)){  
  9.        int diff = left.height-right.height;  
  10.        if(diff<=1||diff>=-1){//绝对值小于等于1  
  11.         //若是是平衡树,才有必要算深度,而后看上级是否是平衡树  
  12.           d.height=left.height>right.height?left.height:right.height;  
  13.           return true  
  14.        }  
  15.    }  
  16.    return false;  
  17. }