这篇主要借用力扣 226. 翻转二叉树来回顾前面学到的二叉树的遍历方法,包括递归法、前序迭代法、迭代统一写法、层序遍历法。
题目如下:
递归法(前中后序)
前序和后序递归可以直接调换代码位置,如果用中序的递归,注意经过中间的翻转,左右孩子已经互换了,所以后面要翻转的应该还是root.left
//前序递归方法,修改一下交换代码和递归的代码的顺序就可以变成后序递归
class Solution {
public TreeNode invertTree(TreeNode root) {
if(root==null)return root;//退出递归条件
//以下3行负责交换
TreeNode temp=root.left;
root.left=root.right;
root.right=temp;
//递归翻转
invertTree(root.left);
invertTree(root.right);
return root;
}
}
//中序递归翻转
class Solution {
public TreeNode invertTree(TreeNode root) {
if(root==null)return root;
invertTree(root.left);
TreeNode temp=root.left;
root.left=root.right;
root.right=temp;
invertTree(root.left);//已经互换过了,所以还是left
return root;
}
}
迭代法
//前序迭代版本
class Solution {
public TreeNode invertTree(TreeNode root) {
if(root==null)return null;
Stack<TreeNode> stk= new Stack<>();
TreeNode node=new TreeNode();//暂存出栈结点
TreeNode temp=new TreeNode();//用于交换
stk.push(root);
while(!stk.isEmpty()){
node=stk.pop();
temp=node.left;
node.left=node.right;
node.right=temp;
if(node.right!=null)stk.push(node.right);
if(node.left!=null)stk.push(node.left);
}
return root;
}
}
//中序迭代版本
class Solution {
public TreeNode invertTree(TreeNode root) {
if(root==null)return null;
Stack<TreeNode> stk= new Stack<>();
TreeNode node=new TreeNode();//暂存出栈结点
TreeNode temp=new TreeNode();//用于交换
stk.push(root);
while(!stk.isEmpty()){
node=stk.pop();
if(node.right!=null)stk.push(node.right);
temp=node.left;
node.left=node.right;
node.right=temp;
if(node.right!=null)stk.push(node.right);
}
return root;
}
}
//后序迭代版本
class Solution {
public TreeNode invertTree(TreeNode root) {
if(root==null)return null;
Stack<TreeNode> stk= new Stack<>();
TreeNode node=new TreeNode();//暂存出栈结点
TreeNode temp=new TreeNode();//用于交换
stk.push(root);
while(!stk.isEmpty()){
node=stk.pop();
if(node.right!=null)stk.push(node.right);
if(node.left!=null)stk.push(node.left);
temp=node.left;
node.left=node.right;
node.right=temp;
}
return root;
}
}
迭代法(统一版本)
可以用一个模板将前中后序迭代的代码风格统一,这种模板的详细介绍在前面的文章:力扣刷题记录-二叉树的前中后序遍历(递归/迭代/迭代统一写法)里面有讲。
//迭代统一法的中序版本,只需修改if里的语句顺序就可改成前序、后序
class Solution {
public TreeNode invertTree(TreeNode root) {
Stack<TreeNode> stack=new Stack<>();
if(root!=null)stack.push(root);
TreeNode temp;
while(!stack.isEmpty()){
TreeNode cur=stack.peek();//cur获取栈顶元素
if(cur!=null){
stack.pop();
if(cur.right!=null)stack.push(cur.right);
stack.push(cur);
stack.push(null);
if(cur.left!=null)stack.push(cur.left);
}
else{
stack.pop();
cur=stack.pop();
temp=cur.left;
cur.left=cur.right;
cur.right=temp;
}
}
return root;
}
}
层序遍历法
//中序+层序
class Solution {
public TreeNode invertTree(TreeNode root) {
Queue<TreeNode> que=new LinkedList<>();
if(root!=null)que.offer(root);
TreeNode temp;
while(!que.isEmpty()){
TreeNode cur=que.poll();
if(cur.left!=null)que.offer(cur.left);
temp=cur.left;
cur.left=cur.right;
cur.right=temp;
if(cur.left!=null)que.offer(cur.left);
}
return root;
}
}
//前序+层序
class Solution {
public TreeNode invertTree(TreeNode root) {
Queue<TreeNode> que=new LinkedList<>();
if(root!=null)que.offer(root);
TreeNode temp;
while(!que.isEmpty()){
TreeNode cur=que.poll();
temp=cur.left;
cur.left=cur.right;
cur.right=temp;
if(cur.left!=null)que.offer(cur.left);
if(cur.right!=null)que.offer(cur.right);
}
return root;
}
}
//后序+层序
class Solution {
public TreeNode invertTree(TreeNode root) {
Queue<TreeNode> que=new LinkedList<>();
if(root!=null)que.offer(root);
TreeNode temp;
while(!que.isEmpty()){
TreeNode cur=que.poll();
if(cur.left!=null)que.offer(cur.left);
if(cur.right!=null)que.offer(cur.right);
temp=cur.left;
cur.left=cur.right;
cur.right=temp;
}
return root;
}
}