平衡二叉树

平衡二叉树

题目要求:

判断一颗二叉树是否为平衡二叉树,若是返回TRUE,否则FALSE

什么是平衡二叉树?

一棵高度平衡二叉树定义为:一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。

注意:

高度:代表的是你从从下往上,从叶子结点(最底层)到根节点

**啥意思?**就是一座楼,我们要从第一层数到最靠近天空的一层,从下到上,第一层相当于叶子结点(最底层)到最高一层(根节点)

深度:反过来,从上到下,从根节点 到最底层的叶子结点

不明白?

一个池塘的深度,你怎么算,是不是从我们所站的地面到下面的塘底的距离(从上到下)

主要采用两种方法:

第一种:递归!永远的神!!

img

 //节点的高度从上往下,深度从下往上
    //确定递归函数的参数和返回值(当前传入的节点,当前传入节点为根节点的树高)
    //标记左右子树的差值是够大于1,采用返回-1的方法
    //明确终止条件
    public int getBalanceHeight(TreeNode root){
        //
        if(root==null) return 0;
        int leftHeight=getBalanceHeight(root.left);
        //进行判断是差值
        if(leftHeight==-1) return -1;
        int rightHeight=getBalanceHeight(root.right);
        if(rightHeight==-1) return -1;
        //建立变量记录平衡二叉树的高度
        int result;
        if((leftHeight-rightHeight)>1){
            return -1;
        }else{
            //以当前节点为根节点的树的高度
            result=1+max(leftHeight,rightHeight);
        }
        //返回参数
        return result;
    }

第二种:迭代(永不磨灭!!)

当中的depth(求深度)我自己推到一遍,清晰明了,看我的注释一般不咋清楚(大神除外)

img

//iteration
    /**使用层序遍历求深度
     * 需要定义专门求高度的函数
     * 通过传入节点的根节点的最大深度求高度
     * 通过栈模拟后续遍历赵每一个节点的高度
     */
    //说明cur节点的最大深度,就是cur的高度
    public int getDepthByIter(TreeNode cur){
        Stack<TreeNode> stack=new Stack<>();
        if(cur!=null) stack.push(cur);
        //init depth
        int depth=0;//record height
        //建立变量记录返回的高度
        int result=0;
        while(!stack.isEmpty()){
            TreeNode node=stack.peek();

            if(node!=null){
                stack.pop();
                //这边是关键,看清楚,我是在一个栈中进行的操作,相当于再次压入栈(因为我们为后面遍历所有子树节点)
                //后序遍历先从底层向上遍历
                stack.push(node);
                //标记根节点
                stack.push(null);
                //记录深度
                depth++;
                if(node.right!=null) stack.push(node.right);
                if(node.left!=null) stack.push(node.left);

            }else{
                //判断由于空节点,弹出空节点
                stack.pop();
                //更新节点
                node=stack.peek();
                stack.pop();
                //这个更新你每次遍历的当前节点到根节点的深度
                depth--;
            }
            result=result>depth?result:depth;//记录最大深度
        }
        return  result;
    }
    //运用栈模拟前序遍历遍历每一个节点时,再去判断左右孩子高度是否符合
    public boolean isBalanced(TreeNode root){
        //init stack
        Stack<TreeNode> stack=new Stack<>();
        if(root==null) return true;
        //根节点压栈
        stack.push(root);
        while(!stack.isEmpty()){
            TreeNode node=stack.peek();//中
            stack.pop();
            //比较左右子树的差值是否大于1
            if(getDepthByIter(node.left)-getDepthByIter(node.right)>1){
                return false;
            }
            if(node.right!=null) stack.push(node.right);//右(空节点不入栈)
            if(node.left!=null)  stack.push(node.left);//左(空加点不如站)

        }
        return true;

    }

手推遍历过程

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值