题目:输入一棵二叉树的根节点,求该二叉树的深度,已知从根结点到叶结点依次经过的结点(含根、叶)形成树的一条路径,最长路径的长度为树的深度
分析:可用递归,如果一棵树只有一个结点则它的深度为1,如果根结点只有左子树而没有右子树,则深度为左子树深度加1,如果根节点只有右子树而没有左子树,则深度为右子树深度加1,如果根节点既有左子树又有右子树,则深度为其最大值加1;或者用非递归,即层序遍历二叉树
import java.util.*;
public class wr39TreeDepth {
// 递归
public static int TreeDepth(TreeNode root){
if(root==null){
return 0;
}
int nleft=TreeDepth(root.left);
int nright=TreeDepth(root.right);
return (nleft>nright)?(nleft+1):(nright+1);
}
// 非递归,层序遍历
// 先将根节点放入队列中,然后每次都从队列中取出一个结点打印该结点的值
// 若这个结点有子结点,则将它的子结点放入队列到尾,直到队列为空
public static int TreeDepth2(TreeNode root){
if(root==null){
return 0;
}
Queue<TreeNode> queue=new LinkedList<TreeNode>();
queue.add(root);
int depth=0;
while(!queue.isEmpty()){
int length=queue.size();
depth++;
for(int i=0;i<length;i++){//一次处理一层的数据
TreeNode temp=queue.poll();//获取并移除
if(temp.left!=null){
queue.add(temp.left);
}
if(temp.right!=null){
queue.add(temp.right);
}
}
}
return depth;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
TreeNode node0=new TreeNode(1);
TreeNode node1=new TreeNode(2);
TreeNode node2=new TreeNode(3);
TreeNode node3=new TreeNode(4);
TreeNode node4=new TreeNode(5);
TreeNode node5=new TreeNode(6);
TreeNode node6=new TreeNode(7);
node0.left=node1;
node0.right=node2;
node1.left=node3;
node1.right=node4;
node2.right=node5;
node4.left=node6;
System.out.println(TreeDepth(node0));
System.out.println(TreeDepth2(node0));
}
}
进一步题目:输入一棵二叉树根节点,判断该树是否为平衡二叉树,如果某二叉树中任意结点的左右子树的深度相差不超过1,那么它就是一棵平衡二叉树
public class wr39TreeBalanced {
// 遍历树的每个结点的时候,调用TreeDepth得到左右子树的深度,若每个结点的左右子树深度差不超过1则是平衡二叉树
// 缺点:每个结点会被重复遍历
public static boolean isBalanced0(TreeNode root){
if(root==null){
return true;
}
int left=TreeDepth(root.left);
int right=TreeDepth(root.right);
int diff=left-right;
if(diff>1 || diff<-1){
return false;
}
return isBalanced0(root.left)&&isBalanced0(root.right);
}
public static int TreeDepth(TreeNode root){
if(root==null){
return 0;
}
int nleft=TreeDepth(root.left);
int nright=TreeDepth(root.right);
return (nleft>nright)?(nleft+1):(nright+1);
}
// 后续遍历每一个结点,在遍历到一个结点之前,就已经遍历了它的左右子树
// 只需在遍历每个结点的时候记录它的深度(某一结点的深度等于它到叶结点的路径的长度)
// 可以一边遍历一边判断每个结点是否是平衡的
public static boolean isBalanced(TreeNode root,int depth){
if(root==null){
depth=0;
return true;
}
int left=0;
int right=0;
if(isBalanced(root.left,left)&&isBalanced(root.right,right)){
int diff=left-right;
if(diff<=1 && diff>=-1){
depth=(left>right)?left+1:right+1;
return true;
}
}
return false;
}
public static boolean isBalanced2(TreeNode root){
int depth=0;
return isBalanced(root,0);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
TreeNode node0=new TreeNode(1);
TreeNode node1=new TreeNode(2);
TreeNode node2=new TreeNode(3);
TreeNode node3=new TreeNode(4);
TreeNode node4=new TreeNode(5);
TreeNode node5=new TreeNode(6);
TreeNode node6=new TreeNode(7);
node0.left=node1;
node0.right=node2;
node1.left=node3;
node1.right=node4;
node2.right=node5;
node4.left=node6;
System.out.println(isBalanced0(node0));
System.out.println(isBalanced2(node0));
}
}