二叉树经典练习题合集(Java实现)

26 篇文章 3 订阅
16 篇文章 3 订阅

二叉树的问题大多是以递归思想求解,也可以利用迭代思想利用队列实现,熟练运用递归对于解决二叉树问题十分重要,本篇博客为一些基础的二叉树问题,对于理解二叉树的结构以及递归思想有着很大的帮助.

本篇文章所有的代码已上传至gitee中:二叉树OJ练习

目录

树的重要概念总结

相同的树

另一颗树的子树 

二叉树的最大深度 

平衡二叉树 

对称二叉树 

迭代实现(利用队列实现)

递归实现 

二叉树的层次遍历 


树的重要概念总结

①结点的度:一个结点含有子树的个数称为该结点的度;

②树的度:一棵树中,所有结点度的最大值称为树的度;

③叶子结点或终端结点:度为0的结点;

④根结点:一棵树中没有双亲的结点;

⑤结点的层次:从根开始定义起,根为第一层,根的子节点为第二层,以此类推;

⑥树的高度或深度:树中结点的最大层次

相同的树

题目链接: 相同的树

题目描述:给你两颗二叉树的根节点p和q,编写一个函数来检验这两颗二叉树是否相同。如果两个树在树结构上相同,并且节点具有相同的值,则认为它们是相同的.

例如:

解题思路

1.首先判断根节点,两棵树若都为空,则返回true;

2.判断两个根节点是否有一个为空,若有,则返回false;

3.判断根节点的值是否相同,若不相同,返回false;

4.递归遍历两颗树的左右子树.

具体实现

public boolean isSameTree(TreeNode p, TreeNode q) {
        if(p == null && q == null) {
            return true;
        }
        if(p == null || q == null) {
            return false;
        }
        if(p.val != q.val) {
            return false;
        }
        return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
    }

另一颗树的子树 

题目链接另一棵树的子树

题目描述: 给你两棵二叉树root和subRoot.检测root中是否包含和subRoot具有相同结构和节点值的子树.如果存在,返回true,否则返回false.

例如:

解题思路

 

本题的解决利用了上一个题目“相同的树”的方法:

将root和subRoot传入isSameTree方法,如果相同,则直接返回true,若不相同,分别将root.left和root.right传入判断.

    public boolean isSubtree(TreeNode root, TreeNode subRoot) {
        if(root == null) {
            return false;
        }
        return isSameTree(root, subRoot) || isSubtree(root.left,subRoot) || isSubtree(root.right,subRoot);
    }
    private boolean isSameTree(TreeNode p, TreeNode q) {
        if(p == null && q == null) {
            return true;
        }
        if(p == null || q == null) {
            return false;
        }
        if(p.val != q.val) {
            return false;
        }
        return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
    }

二叉树的最大深度 

题目链接二叉树的最大深度

 题目描述:给定一棵二叉树,找出其最大深度.二叉树的深度为根节点到最远叶子节点的最长路径上的节点数.

例如:

 解题思路

依次递归求左子树和右子树的高度,最终返回左子树/右子树的高度+1

代码实现

    public int maxDepth(TreeNode root) {
        if(root == null) {
            return 0;
        }
        int leftH = maxDepth(root.left);
        int rightH = maxDepth(root.right);
        return leftH > rightH ? (leftH+1) : (rightH+1);
    }

平衡二叉树 

题目链接平衡二叉树

题目描述:给定一棵二叉树,判断其是否为高度平衡二叉树。

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

例如:

 

解题思路: 

编写一个方法:一边求二叉树的高度,一边判断平衡,如果该子树平衡,则返回其高度,反之返回-1.

代码如下

    public boolean isBalanced(TreeNode root) {
        return maxDepth(root) >= 0;//等于0是因为当二叉树为空时,返回true
    }
    private int  maxDepth(TreeNode root) {
        if(root == null) {
            return 0;
        }
        int leftH = maxDepth(root.left);
        int rightH = maxDepth(root.right);
        if(leftH >= 0 && rightH >= 0 && Math.abs(leftH - rightH) <= 1) {
            return Math.max(leftH,rightH) + 1;
        } else {
            return -1;
        }
    }

对称二叉树 

题目链接对称二叉树

题目描述:给你一个结点root,判断它是否为对称轴.

例如:

 

解题思路

有两种方法可以实现:①迭代;②递归.

迭代实现(利用队列实现)

如上图所示,利用队列完成判断该二叉树是否为对称二叉树,首先判断root是否为null,若为null直接返回true,否则进行如下操作:

1.将root的左孩子和右孩子分别入队

 

2.利用while语句判断队列目前是否为空,若不为空则一直进行循环操作:

①利用TreeNode定义p和q,用来接收出队的两个结点,若这两个结点均为null,则继续循环

②若p和q中只有一个为空或者p.val != q.val,则返回false;

③先将p的左孩子和q的右孩子入队,再将p的右孩子和q的左孩子入队.

 

3.如果上述操作完成,且未跳出,则返回true 

具体代码实现

    public boolean isSymmetric(TreeNode root) {
        if(root == null) {
            return true;
        }
        return check(root.left, root.right);
    }
    private boolean check(TreeNode p, TreeNode q) {
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(p);
        queue.offer(q);
        while(!queue.isEmpty()) {
            p = queue.poll();
            q = queue.poll();
            if(p == null && q == null) {
                continue;
            }
            if(p == null || q == null || p.val != q.val) {
                return false;
            }
            queue.offer(p.left);
            queue.offer(q.right);

            queue.offer(p.right);
            queue.offer(q.left);
        }
        return true;
    }

递归实现 

该方法的时间复杂度为O(n),其check方法的主要思想为:

1.如果p和q都为null则对称;

2.如果p和q有一个为空或者q.val != p.val,则返回false;

3.递归遍历check(p.left,q.right) && check(p.right,q.left)

    public boolean isSymmetric(TreeNode root) {
        if(root == null) {
            return true;
        }
        return check(root.left, root.right);
    }
    private boolean check(TreeNode p, TreeNode q) {
        if(p == null && q == null) {
            return true;
        }   
        if(p == null || q == null || p.val != q.val) {
            return false;
        }
        return check(p.left,q.right) && check(p.right,q.left);
    }

二叉树的层次遍历 

题目链接二叉树的层次遍历

题目描述: 给你二叉树的根节点root,返回其结点值的层序遍历(即逐层的,从左到右访问所有节点).

 例如:

解题思路

根据题目给出的初始模板,可以看出本题意在利用顺序表解决问题. 

以上述例子为例,可以抽象出实现该问题需要如下的顺序表

首先将根节点入队,之后判断如下几个条件:

①该节点左孩子是否为空,若不为空,则将其加入队列,若为空则不做处理;

②再判断其右孩子是否为空,若不为空,则将其加入队列,若为空则不做处理;

③以size来作为每一层结点结束的标志,当size为0时,结束该层的循环,进入下一层的循环.

具体代码实现: 

    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> ret = new ArrayList<>();
        if(root == null) {
            return ret;
        }
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while(!queue.isEmpty()) {
            List<Integer> curRow = new ArrayList<>();
            int size = queue.size();
            while(size != 0) {
                TreeNode cur = queue.poll();
                curRow.add(cur.val);
                if(cur.left != null) {
                    queue.offer(cur.left);
                }
                if(cur.right != null) {
                    queue.offer(cur.right);
                }
                size--;
            }
            ret.add(curRow);
        }
        return ret;
    }

 

 

 

 

 

 

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Li_yizYa

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值