二叉树的前序遍历
前中后序 遍历 其实方法都一样,就是把节点的访问顺序变一下,代码都一模一样,只是换顺序罢了
题目:
思路: 本题要求将遍历到的节点放入一个List中返回
- 前序遍历顺序:根节点——>左孩子节点——>右孩子节点
- 先判断根节点,如果根节点为空,直接返回list
- 将当前访问的根节点存入顺序表中
- 然后递归访问左孩子节点
- 最后递归访问右孩子节点
实现代码:
class Solution { List<Integer> list = new ArrayList<>(); public List<Integer> preorderTraversal(TreeNode root) { if(root==null){//根节点空 return list;//直接返回顺序表 } list.add(root.val);//将当前访问的根节点的值存入顺序表 preorderTraversal(root.left);//访问左节点 preorderTraversal(root.right);//访问右节点 return list; } }
中序遍历
题目:
思路: 本题要求将遍历到的节点放入一个List中返回
- 中序遍历顺序:左孩子节点——>根节点——>右孩子节点
- 先判断当前根节点,如果根节点为空,直接返回list
- 访问左孩子节点
- 将当前访问的根节点值存入顺序表
- 最后访问右孩子节点
实现代码:
class Solution { List<Integer> list = new ArrayList<>(); public List<Integer> inorderTraversal(TreeNode root) { if(root==null){//判断当前根节点是否为空 return list; } inorderTraversal(root.left);//访问左孩子节点 list.add(root.val);//将当前访问的根节点的值存入顺序表 inorderTraversal(root.right);//访问右孩子节点 return list; } }
后续遍历
题目:
思路: 本题要求将遍历到的节点放入一个List中返回
- 后序遍历顺序:左孩子节点——>右孩子节点——>根节点
- 先判断当前根节点,如果根节点为空,直接返回list
- 访问左孩子节点
- 访问右孩子节点
- 最后将当前访问的根节点值存入顺序表
实现代码:
class Solution { List<Integer> list = new ArrayList<>(); public List<Integer> postorderTraversal(TreeNode root) { if(root==null){//判断根节点是否为空 return list; } postorderTraversal(root.left);//访问左孩子节点 postorderTraversal(root.right);//访问右孩子节点 list.add(root.val);//将当前访问的根节点的值存入顺序表 return list; } }
判断两棵树是否是相同树
题目:
思路:
首先要明确两棵树相同,指的是左子树和右子树都相同,且值也相同
先判断,两棵树的根节点是否为空,如果两棵树的根节点都是空,那这两棵树相同,直接返回true;
如果两棵树只有一棵树的根节点为空,另一棵树的根节点不为空,那这两棵树必不相同,直接返回false
如果两棵树的根节点都不为空,那就比较其值,如果值不一样,两棵树就不相同,返回false
当以上条件都没返回false,也就是说两棵树的根节点都相同,那么就用 递归 去判断他们的左右孩子节点是否相同,进行套娃,即可
实现代码:
class Solution { public boolean isSameTree(TreeNode p, TreeNode q) { //2个都为空 if(p == null && q == null) { return true; } //只有一个不为空 if(p == null || q == null) { return false; } //都不为空 if(p.val != q.val) { return false; } //p和q不为空 且对应的值 是相同的 那么去判断两棵树的左树和右树 return isSameTree(p.left,q.left) && isSameTree(p.right,q.right); } }
另一棵树是否是当前树的子树
题目:
思路:
- 这题需要自己额外写一个
判断是否是相同树的方法
(参考上一题,实现代码一模一样) - 如果当前树的根节点是空,则另一棵树肯定不是它的子树
- 如果另一棵树的根节点是空,则肯定是当前树的子树
- 每往下递归一个节点,就要判断一次,当前根节点代表的树是否和另一棵树是相同树
实现代码:
class Solution { public boolean isSubtree(TreeNode root, TreeNode subRoot) { if (subRoot == null) return true; //另一棵树的根节点是空,则肯定是当前树的子树 if (root == null) return false; //当前树的根节点是空,则另一棵树肯定不是它的子树 return isSubtree(root.left,subRoot)||isSubtree(root.right,subRoot)||isSameTree(root,subRoot);//没往下走一个节点,都要判断一次当前根节点代表的树是否和另一棵树是相同树 } public boolean isSameTree(TreeNode s, TreeNode t) { if (s == null && t == null) return true;//都为空 if (s == null || t == null) return false;//有一个不为空 if(s.val!=t.val) return false;//值不同,返回false //值都相同,继续下一个节点的判断 return isSameTree(s.left, t.left) && isSameTree(s.right, t.right); } }
求二叉树最大深度
题目:
思路:
先搞懂一个问题,就是二叉树的深度 = 左子树深度和右子树深度两者取较大值
所以有一个公式,最大深度=左子树深度>右子树深度?左子树深度:右子树深度
利用公式,可以进行递归
先判断当前根节点是否空,空的话返回0(即深度为0)
然后依次判断左子树和右子树的深度
注意:返回的时候要+1,因为根节点也算一层
实现代码:
class Solution { public int maxDepth(TreeNode root) { if(root==null){//如果根节点空,返回0 return 0; } int a=maxDepth(root.left);//求左子树高度 int b=maxDepth(root.right);//求右子树高度 return (a > b ? a : b )+ 1;//递归公式 } }
判断二叉树是否是平衡二叉树
题目:
思路:
- 本题中,一棵高度平衡二叉树定义为:
一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1
。 - 采取从下往上看的思路,额外写一个判断树高度的方法
- 判断当前根节点的左子树高度和右子树高度之差的绝对值是否不超过1
- 符合平衡条件则返回子树高度,否则返回
实现代码:
class Solution { public boolean isBalanced(TreeNode root) { if(height(root)>=0) return true; else return false; } //从下往上看 public int height(TreeNode root) { if (root == null) //根节点空,返回0 return 0; int left = height(root.left);//获得左节点高度 if(left == -1) return -1; int right = height(root.right);//获得右节点高度 if(right == -1) return -1; return Math.abs(left - right) <=2 ? Math.max(left, right) + 1 : -1; //如果左子树和右子树高度差绝对值不大于1,返回子树的高度,否则返回-1 } }
判断镜像二叉树
题目:
思路:
- 这道题其实就是
判断左右子树是否相同
,只不过还需要做一点小小的改动
- 因为要判断是不是镜像,所以改动就是
左子树的左孩子值 要等于 右子树的右孩子值,左子树的右孩子值 要等于 右子树的左孩子值
实现代码:
class Solution { public boolean isSymmetric(TreeNode root) { if(root==null){ return false; } return isSame(root.left,root.right);//左右子树符合镜像条件,则是镜像二叉树 } public boolean isSame(TreeNode a,TreeNode b){ if(a == null && b ==null) return true; if(a == null || b ==null) return false; if(a.val != b.val) return false; //关键在于最后一行代码 //左子树的左孩子值 要等于 右子树的右孩子值 //左子树的右孩子值 要等于 右子树的左孩子值 return isSame(a.left,b.right)&&isSame(a.right,b.left); } }