对称二叉树
什么是对称二叉树?
如上图所示
判断一个二叉树是否为对称二叉树?
判断步骤:1.头节点的左子树节点是否等于右子树节点;
2.左子树节点的左子树节点是否等于右子树节点的右子树节点;
3.左子树节点的右子树节点是否等于右子树节点的左子树节点;
是否等于的情况可以分为四种类型:
1.left == null && right == null; true
2.left != null && right == null; false
3.left == null && right != null; false
4.left.val != right.val ; false
注意:运用迭代法时2.3.4条件可用 || 合并
同样判断对称二叉树可用迭代法和递归法
完整代码如下:
迭代法
class Solution {
public boolean isSymmetric(TreeNode root) {
Queue<TreeNode> queue=new LinkedList<TreeNode>();
queue.offer(root.left); //首先放入头节点的左子树节点和右子树节点
queue.offer(root.right);
while(!queue.isEmpty()){
TreeNode leftNode =queue.poll(); //分别抛出后进行对称树判断
TreeNode rightNode =queue.poll();
if(leftNode==null&&rightNode==null){
continue; //注意continue
}
if(leftNode==null||rightNode==null||leftNode.val!=rightNode.val){
return false;
}
queue.offer(leftNode.left); //放入左子树节点的左子树节点和右子树节点的右子树节点
queue.offer(rightNode.right);
queue.offer(leftNode.right); //放入左子树节点的右子树节点和右子树节点的左子树节点
queue.offer(rightNode.left);
}
return true;
}
}
递归法
class Solution {
public boolean isSymmetric(TreeNode root) {
return compare(root.left,root.right);
}
public boolean compare(TreeNode left,TreeNode right){
if(left==null&&right==null){
return true;
}else if(left!=null&&right==null){
return false;
}else if(left==null&&right!=null){
return false;
}else if(left.val!=right.val){
return false;
}
boolean compareOutside=compare(left.left,right.right);
boolean compareInside=compare(left.right,right.left);
return compareOutside&&compareInside;
}
}
二叉树的层次遍历
二叉树两种遍历方式:
- 深度优先遍历:借助栈 (前序遍历 中序遍历 后序遍历)
- 广度优先遍历:借助队列 (层次遍历)
二叉树的层次遍历:
注意:因为是层次遍历,所以要分层!见下图:
输出结果没有分层,所以答案错误。
注意:List<Integer> result =new ArrayList<Integer>要放在while(!que.isEmpty())里 不然会k次
思路:
- 首先List<Integer>指的是存int类型数据的列表
List<List<Integer>>指的是存【int类型数据的列表】类型数据的列表
2.定义一个全局列表 List<List<Integer>> 存放分层后的数据
3.在主函数里 1.调用方法 2.返回全局列表
4.定义一个层次遍历的方法 迭代法(也可用递归法)
创新点:1.定义一个队列 先进先出 Queue<TreeNode> que =new LinkedList<TreeNode>();
2.定义一个存放数值的列表 List<Integer> result =new ArrayList<Integer>();
3.想要分层效果 需要定义一个 int len =queue.size(); 每取一次 len--
4.先取中节点,再取左子树节点和右子树节点
5.最后把列表的值返回给全局列表。
完整代码如下:
递归法
class Solution {
List<List<Integer>> resList =new ArrayList<List<Integer>>(); //全局列表要定义在开头
public List<List<Integer>> levelOrder(TreeNode root) {
checkFun02(root,0); //层次数一开始为0
return resList; //返回全局列表
}
public void checkFun02(TreeNode node,Integer deep){
if(node==null) return;
deep++; //每次都要加一次层数
while(resList.size()<deep){
List<Integer> result =new ArrayList<Integer>(); //定义局部列表
resList.add(result); //把局部列表加入到全局列表中
}
resList.get(deep-1).add(node.val);
checkFun02(node.left,deep);
checkFun02(node.right,deep);
}
}
迭代法
class Solution {
List<List<Integer>> resList =new ArrayList<List<Integer>>();
public List<List<Integer>> levelOrder(TreeNode root) {
checkFun02(root);
return resList;
}
public void checkFun02(TreeNode node){
if(node==null) return;
Queue<TreeNode> queue = new LinkedList<TreeNode>();
queue.offer(node);
while(!queue.isEmpty()){
List<Integer> result =new ArrayList<Integer>(); //局部列表定义在中间
int len =queue.size(); //定义层数
while(len>0){
TreeNode node1 =queue.poll();
result.add(node1.val);
if(node1.left!=null){queue.offer(node1.left);}
if(node1.right!=null){queue.offer(node1.right);}
len--;
}
resList.add(result); //局部列表加入到全局列表中
}
}
}
翻转二叉树
翻转二叉树非常简单 只需要定义一个swap方法 交换一下左子树节点和右子树节点
注意:中序遍历比较特别
什么是翻转二叉树?
如上图所示
分为层次遍历法和前(中、遍历后)序
完整代码如下:
层次遍历法:
class Solution {
public TreeNode invertTree(TreeNode root) {
if(root==null){return null;}
Queue<TreeNode> queue =new LinkedList<TreeNode>();
queue.offer(root);
while(!queue.isEmpty()){
int size =queue.size();
while(size-->0){
TreeNode node =queue.poll();
swap(node);
if(node.left!=null){queue.offer(node.left);}
if(node.right!=null){queue.offer(node.right);}
}
}
return root;
}
public void swap(TreeNode node){
TreeNode tmp =node.left;
node.left=node.right;
node.right=tmp;
}
}
前(中、后)序遍历法:
class Solution {
public TreeNode invertTree(TreeNode root) {
if(root==null){return null;}
invertTree(root.left);
invertTree(root.right);
swap(root);
return root;
}
public void swap(TreeNode root){
TreeNode tmp=root.left;
root.left=root.right;
root.right=tmp;
}
}