二叉树(二)Java实现

   /**
     *求二叉树的高度
     * 整棵树的高度 = Math.max(左树高度, 右树高度) + 1
     * root会把每个节点都走一遍    时间复杂度o(N)
     * @param root
     * @return
     */
    public int getHeight(TreeNode root) {
        if(root == null) {
            return 0;
        }
        int leftHeight = getHeight(root.left);
        int rightHeight = getHeight(root.right);

        return leftHeight > rightHeight ? leftHeight + 1 : rightHeight + 1;

        //这样写会存在超出运行时间的问题
        //return getHeight(root.left) > getHeight(root.right) ? getHeight(root.left) + 1 : getHeight(root.right) + 1;
    }

   /**判断两棵树是否相同
     * 时间复杂度: O(min(m,n))
     * @param p  m个节点
     * @param q  n个节点
     * @return
     */
    public boolean isSameTree(TreeNode p, TreeNode q) {
        /*
        根节点的结构和值一样  =>  p和q都不为空并且p和q的值一样
        左子树的结构和值一样 && 右子树的结构和值一样   =>  p.left  q.left && p.right  q.right
         */
        //1.一个为空 一个不为空 [结构上不一样]
        if(p != null && q == null || p == null && q != null){
            return false;
        }

        //2.第一步走完之后,要么都为空,要么都不为空  两个都是空
        if(p == null && q == null){
            return true;
        }

        //3.都不为空
        if(p.val != q.val){
            return false;
        }

        //4.此时代表2个都不为空同时val值也是一样的!
        //5.说明根节点相同,接下来判断两棵树的左和两棵树的右是不是同时相同
        return isSameTree(p.left,q.left) && isSameTree(p.right,q.right);
    }
}

   /** 判断一棵树是否为另一棵树的子树
     * 时间复杂度:O(m*n)
     * @param root   m
     * @param subRoot  n
     * @return
     */
    public boolean isSubtree(TreeNode root, TreeNode subRoot) {
        /*
        1.去判断两棵树是不是两棵相同的树
        2.如果不是两棵相同的树,那么有可能是root的左子树的子树也有可能是root右子树的子树
         */
        if(root == null) {
            return false;
        }
        if(isSameTree(root, subRoot)) {
            return true;
        }
        if(isSubtree(root.left, subRoot)) {
            return true;
        }
        if(isSubtree(root.right, subRoot)) {
            return true;
        }
        return false;
    }

/**翻转二叉树
     * 时间复杂度:
     * @param root
     * @return
     */
    public TreeNode invertTree(TreeNode root) {
        if(root == null) {
            return null;
        }
        //减少一些递归和交换的次数
        if(root.left == null && root.right == null) {
            return root;
        }
        TreeNode tmp = root.left;
        root.left = root.right;
        root.right = tmp;
        invertTree(root.left);
        invertTree(root.right);

        return root;
    }

平衡二叉树 是指该树所有节点的左右子树的深度相差不超过 1。

   /**平衡二叉树
     *时间复杂度:O(N^2)
     * @param root
     * @return
     */
    //1.当前root的左子树和右子树的高度差 <= 1
    //2.同时满足 root的左子树平衡 && root的右子树平衡
    public boolean isBalanced(TreeNode root) {
        if(root == null) {
            return true;
        }
        int leftH = maxDepth(root.left);
        int rightH = maxDepth(root.right);

        return Math.abs(leftH - rightH) <= 1 && isBalanced(root.left) && isBalanced(root.right);

    }

    public int maxDepth(TreeNode root) {
        if(root == null) {
            return 0;
        }
        int leftHeight = maxDepth(root.left);
        int rightHeight = maxDepth(root.right);

        return leftHeight > rightHeight ? leftHeight + 1 : rightHeight + 1;
    }
/**平衡二叉树优化
     *时间复杂度:O(N)
     * @param root
     * @return
     */
    public boolean isBalanced2(TreeNode root) {
        if(root == null) {
            return true;
        }
        return maxDepth2(root) >= 1;
    }

    public int maxDepth2(TreeNode root) {
        if(root == null) {
            return 0;
        }
        int leftHeight = maxDepth2(root.left);
        if(leftHeight < 0) {
            return -1;
        }
        int rightHeight = maxDepth2(root.right);
        if(rightHeight < 0) {
            return -1;
        }
        if(Math.abs(leftHeight - rightHeight) <= 1) {
            return Math.max(leftHeight, rightHeight) + 1;
        }else {
            return -1;
        }
    }

/**对称二叉树
     * 时间复杂度:O(N)
     * @param root
     * @return
     */
    public boolean isSymmetric(TreeNode root) {
        if(root == null) {
            return true;
        }
        return isSymmetricChild(root.left, root.right);
    }

    public boolean isSymmetricChild(TreeNode leftTree, TreeNode rightTree) {
        //1.检查结构是否相同 -> 一个为空 一个不为空
        if(leftTree != null && rightTree == null ||
                leftTree == null && rightTree != null) {
            return false;
        }
        //2.检查结构是否相同 -> 处理【两个都为空】和两个都不为空
        if(leftTree == null && rightTree == null) {
            return true;
        }
        //3.检查结构是否相同 -> 处理两个都为空和【两个都不为空,判断值一样吗】
        if(leftTree.val != rightTree.val) {
            return false;
        }
        //4.此时两个引用都不为空同时节点的值一样
        //5.开始判断是否对称
        //6.满足左子树的左和右子树的右对称同时左子树的右和右子树的左对称
        return isSymmetricChild(leftTree.left, rightTree.right) &&
                isSymmetricChild(leftTree.right, rightTree.left);
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值