BinaryTree 的高度指其根到叶子结点路径中最长的距离 比如如下binarytree:
2
3 1
4 2 3 5
6 7
9
从2到9要经历2-1-5-7-9 5个节点(包括root) 所以其高度为5
也可以解释成一个节点的高度,等于其左右子树中高度较高的那一支的高度+1(因为多了一个节点)
第二种理解对于程序求解高度较为方便。具体实现中使用递归,求解每个子结点的高度,并递归到根节点,根节点高度去子结点高度较大的一个并加1. 最后root节点返回的高度值既为binarytree的高度。其中当当前节点为空时,返回0;
此方法遍历binarytree每个节点,复杂度为O(N)
Java 代码如下:
public int getHeight(Node root){
if(root==null){
return 0;
}
else if(getHeight(root.left)>=getHeight(root.right)){
return getHeight(root.left)+1;
}
else return getHeight(root.right)+1;
}
同理,当每个节点高度可求时,即可判断平衡树。
平衡树定义为对于每个节点,子树的高度差不大于1.所以通过遍历每个节点的左右节点,并判断高度差即可判断该树是否为平衡树。
public boolean isBalanceTree(Node root){
/*
* For getHeight function the first level nodes call for N times with N nodes to calculate height
* The second level nodes call N/2 order times with N/2 order nodes in each subtree and 2 roots
* The n level nodes call N/2^(N-1)order times with N/2^(N-1) order nodes in 2^(N-1) roots
* So there are N calls in each level
* For N input size, there are logN levels. So the time complexity is O(NlogN).
*/
if(root==null){
return true;
}
int diff=Math.abs(getHeight(root.left)-getHeight(root.right));
if (diff>1){
return false;
}
else return isBalanceTree(root.left)&&isBalanceTree(root.right);
}
其复杂度为O(N*logN),自行推导如上(并不一定准确。。。)
然后发现在ctci上有另一种O(N)的算法:
因为在求每个节点的高度的时候都要求其左右子结点的高度,因此可以在这个时候进行判断,如果存在大于1的,直接返回-1跳出即可。省去了外层判断函数的遍历过程
代码:
public int getTreeHeight(Node root){
/*
We determine the diff in calculate each node's height
O(n)
*/
if(root==null){
return 0;
}
else{
int heightLeft=getTreeHeight(root.left);
if(heightLeft==-1){
return -1;
}
int heightRight=getTreeHeight(root.right);
if(heightRight==-1){
return -1;
}
return Math.max(heightLeft, heightRight);
}
}