剑指offer:面试题55-2:平衡二叉树

博客围绕判断二叉树是否为平衡二叉树展开。先明确平衡二叉树定义,给出两种思路,思路一是遍历每个节点判断左右子树高度差,思路二是后序遍历且剪枝,只遍历一次。还给出功能和特殊测试用例,最后提到判断树不平衡可剪枝。

题目

输入一棵二叉树的根结点,判断该树是不是平衡二叉树。如果某二叉树中任意结点的左右子树的深度相差不超过1,那么它就是一棵平衡二叉树。

思路

首先,明确平衡二叉树的定义:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。

  • 思路一,在55-1:树的深度的基础上,遍历每个节点,并判断每个节点的左右子树高度差是否超过1,若超过,则不是平衡二叉树;若所有节点都不超过,则是平衡二叉树。
  • 思路二,上述思路显然一个节点会被遍历多次。因此思路二给出只遍历一次的思路(且有剪枝)。即使用后序遍历的方式遍历二叉树的节点,这样遍历父节点时已经遍历过其左右子树,只需要记录下每个节点的深度,即可在一次后序遍历后,知道这棵树是否平衡。

测试用例

1.功能测试(左斜树、右斜树、平衡或者不平衡树)
3.特殊测试(一个结点,null)

Java实现

实现一

public class IsBalancedTree {
    public static class TreeNode{
        int val = 0;
        TreeNode left = null;
        TreeNode right = null;

        public TreeNode(int val) {
            this.val = val;
        }
    }

    /**
     * 方法一
     * @param root
     * @return
     */
    public boolean IsBalanced_Solution(TreeNode root) {
        if (root == null) return true;
        if (Math.abs(treeDepth(root.right) - treeDepth(root.left)) <= 1) {
            return IsBalanced_Solution(root.left) && IsBalanced_Solution(root.right);
        } else {
            return false;
        }
    }


    public int treeDepth(TreeNode root) {
        if (root == null) {
            return 0;
        }
        int leftDepth = treeDepth(root.left);
        int rightDepth = treeDepth(root.right);
        return 1 + Math.max(leftDepth, rightDepth);
    }
}

实现二

public class IsBalancedTree {
    public static class TreeNode{
        int val = 0;
        TreeNode left = null;
        TreeNode right = null;

        public TreeNode(int val) {
            this.val = val;
        }
    }
    /**
     * 方法二
     * 利用后续遍历,能够先遍历子节点,记录下深度,再计算父节点是否balance,就能够只遍历一遍。
     * @param root
     * @return
     */
    public boolean IsBalanced_Solution(TreeNode root) {
        if (root == null) return true;
        return treeDepthPruning(root) != -1;
    }


    public int treeDepthPruning(TreeNode root) {
        if (root == null) {
            return 0;
        }
        int leftDepth = treeDepth(root.left);
        if (leftDepth == -1) return -1;          // 这是剪枝
        int rightDepth = treeDepth(root.right);
        if (rightDepth == -1) return -1;         // 这是剪枝
        if (Math.abs(leftDepth - rightDepth) > 1) {
            return -1;
        } else {
            return 1 + Math.max(leftDepth, rightDepth);
        }
    }

}

收获

  1. 判断树不平衡后,可以直接退出(剪枝),不需要遍历完整棵树。
【系统开发环境】 1. 系统环境:MS WINDOWS 2003 +IIS 6.02. 数 据 库:MS Access20033. 测试浏览器:腾讯TT浏览器 微软IE浏览器6.0 微软IE浏览器7.0 4. 系统分辨率:1024X768 ☆系统前台简介☆ 1.申请加入免费友情链接网的网站按最后点进的时间排序首页和分类显示链接,分类以昨日点入时间为准,每晚十二点后生成静态。2.每来访一个IP,就会自动排到第一(无延时),自动收录功能开通的站要刷新一下才能显示,当天来路不同,显示颜色也不同3.首页白天3分钟,晚上5分钟自动更新一次,全站24小时手动更新一次。4.站内搜索功能。5.网址库中分离出的【名站导航】【实用工具】【友情链接】 ☆系统后台功能☆设置网站的基本信息。广告位设置。***(开通关闭新站提交,开通关闭自动审核)***。非法词拦截,非法网址拦截。管理员帐号/密码更改。网站文字广告管理 修改,添加! 客户留言管理,回复,修改,删除留言。黑客入侵查看,删除黑客入侵数据!添加删除分类。分类可修改可设置首页是否显示。酷站可设置首页是否显示。添加删除修改网址内容,是否推荐,是否审核。可从网址库中分离出【名站导航】【实用工具】【友情链接】【名站导航】【实用工具】可由快速通道添加和管理。【友情链接】从网址列表中设置。常用维护共三项,删除所有未审核的网站,开通所有有点入的网站,删除所有重复提交的网站站内搜索功能。生成htm分类页面,生成htm主页及其它页面。可修改主页,分类及其它页面模板。具有数据库【备份】【压缩】【恢复】功能。具有在线广告管理功能。(5个广告位),非常方便!新增站长添加的网址和用户添加的网址分开独立管理防注入 黑客攻击入侵查看,黑客入侵文件清理!更改验证码路径,免去别人可从验证码右键属性猜到后台。☆安装使用方法☆1.在支持ASP的服务器上解开本软件包。2.数据库文件在data目录,已经做了防下载处理。3.后台登录地址在admin8888/index.asp,默认管理员账号:admin,密码:admin。4.进入后台根据提示设置你网站的基本信息。5.生成全站一次。爱尚数码,西部数码代理商,购买主机享受西部数码官方价格8折优惠
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值