求二叉树的深度,判定二叉树是否是平衡二叉树(java)

题目描述:

输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。

输入:

第一行输入有n,n表示结点数,结点号从1到n。根结点为1。 n <= 10。
接下来有n行,每行有两个个整型a和b,表示第i个节点的左右孩子孩子。a为左孩子,b为右孩子。当a为-1时,没有左孩子。当b为-1时,没有右孩子。

输出:

输出一个整型,表示树的深度。

样例输入:

3
2 3
-1 -1
-1 -1

样例输出:

2

这里写图片描述
本题求二叉树的深度,可以用递归来实现。如果根节点只有左子树,那么高度则为左子树的高度+1;如果根节点只有右子树,那么高度则为右子树的高度+1;若根节点左右子树都存在,那么高度则为左右子树中高度较大的那一个+1。如此依次类推下去。代码如下:

//二叉树
class TreeNode{
    int value;
    TreeNode right = null;
    TreeNode left = null;
    TreeNode(int value){
        this.value = value;
        this.left = this.right = null;
    }
}
//获得一颗二叉树的深度
    public static int getTreeDepth(TreeNode root){
        if(root==null)
            return 0;
        int left = getTreeDepth(root.left);
        int right = getTreeDepth(root.right);   
        return left>right?left+1:right+1;
    }

那么,问题来了。如果想要判定这颗树是否是平衡二叉树呢?
一种比较直接的方法是,遍历整棵树,获得每个节点的左右孩子节点的高度,若没有左或右孩子节点,可以看做其左右的孩子节点为0。然后比较孩子节点的高度之差,若高度之差的绝对值是小于1的,则认为这个这个节点的左右子树是平衡的。可以如下表示出来:

//判断一颗树是否是平衡二叉树
    public static boolean isBalance(TreeNode root){
        if(root==null)
            return true;
        int left = getTreeDepth(root.left);
        int right = getTreeDepth(root.right);
        int diff = left-right;
        if(diff>1||diff<-1){
            return false;
        }
        return isBalance(root.left)&&isBalance(root.right);
    }

写到此处,会发现这种方法,在遍历是会存在大量的重复。例如在判定根节点是否是平衡的过程中,我们会调用getTreeDepth函数,输入左子树的根节点2,依次遍历4,5,7;然后在判断节点2的时候,又要遍历4,5,7,所以会存在很多的重复。
我们会想到二叉树的后续遍历方式,就是先判定左右子树是,在遍历到节点之前,我们已经遍历到了它的左右子树,并将左右子树的高度记录下来,我们就可以一边遍历,一边判定每个节点是不是平衡的了。于是,就有了以下代码:

//保存节点的高度
class Depth{
    int depth;
}
//后序遍历的方式遍历二叉树的每一个结点,在遍历到一个结点之前我们已经遍历了它的左右子树
    public static boolean isBalanced(TreeNode root,Depth de){
        if(root==null){
            de.depth = 0;
            return true;
        }
        Depth left = new Depth();
        Depth right = new Depth();
        if(isBalanced(root.left,left)&&isBalanced(root.right,right)){
            int leftDep = left.depth;
            int rightDep = right.depth;
            int diff=leftDep-rightDep;  
            if(diff<=1 && diff>=-1){  
                de.depth = leftDep>rightDep?leftDep+1:rightDep+1; 
                return true; 
            }
        }
        return false;
    }

已经AC完整代码:

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;

class Depth{
    int depth;
}
class TreeNode{
    int value;
    TreeNode right = null;
    TreeNode left = null;
    TreeNode(int value){
        this.value = value;
        this.left = this.right = null;
    }
}
public class jobdu1350 {
    //获得一颗二叉树的深度
    public static int getTreeDepth(TreeNode root){
        if(root==null)
            return 0;
        int left = getTreeDepth(root.left);
        int right = getTreeDepth(root.right);   
        return left>right?left+1:right+1;
    }
    //判断一颗树是否是平衡二叉树
    public static boolean isBalance(TreeNode root){
        if(root==null)
            return true;
        int left = getTreeDepth(root.left);
        int right = getTreeDepth(root.right);
        int diff = left-right;
        if(diff>1||diff<-1){
            return false;
        }
        return isBalance(root.left)&&isBalance(root.right);
    }
    //后序遍历的方式遍历二叉树的每一个结点,在遍历到一个结点之前我们已经遍历了它的左右子树
    public static boolean isBalanced(TreeNode root,Depth de){
        if(root==null){
            de.depth = 0;
            return true;
        }
        Depth left = new Depth();
        Depth right = new Depth();
        if(isBalanced(root.left,left)&&isBalanced(root.right,right)){
            int leftDep = left.depth;
            int rightDep = right.depth;
            int diff=leftDep-rightDep;  
            if(diff<=1 && diff>=-1){  
                de.depth = leftDep>rightDep?leftDep+1:rightDep+1; 
                System.out.println(de.depth);
                return true; 
            }
        }
        return false;
    }
    public static void main(String[] args) throws Exception {
        StreamTokenizer cin = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
        while(cin.nextToken()!=cin.TT_EOF){
            int n = (int)cin.nval;
            int sign = 1;
            TreeNode []array = new TreeNode[n+1];
            array[sign++] = new TreeNode(1);
            TreeNode root = array[1];
            for(int i=1;i<=n;i++){
                cin.nextToken();
                int left =(int) cin.nval;
                cin.nextToken();
                int right =(int) cin.nval;
                if(left!=-1){
                    array[sign] =new TreeNode(left);
                    array[i].left = array[sign];
                    sign++;
                }else{
                    array[i].left = null;
                }
                if(right!=-1){
                    array[sign] = new TreeNode(right);
                    array[i].right = array[sign];
                    sign++;
                }               
            }
            int depth = getTreeDepth(root);
            System.out.println(depth);
            Depth de = new Depth();
            System.out.println(isBalanced(root,de));
        }
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值