题目
给定一个二叉树的根节点 root ,返回它的 中序 遍历。
示例 1:
输入:root = [1,null,2,3]
输出:[1,3,2]
示例 2:
输入:root = []
输出:[]
示例 3:
输入:root = [1]
输出:[1]
示例 4:
输入:root = [1,2]
输出:[2,1]
示例 5:
输入:root = [1,null,2]
输出:[1,2]
题解一 递归
class Solution {
List<Integer> res;
public List<Integer> inorderTraversal(TreeNode root) {
res=new ArrayList<>();
if(root==null){
return res;
}
inOrder(root);
return res;
}
private void inOrder(TreeNode root){
if(root==null){
return;
}
inOrder(root.left);
res.add(root.val);
inOrder(root.right);
}
}
//官方题解 中序遍历的时候用递归一般返回都是void,注意这点
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<Integer>();
inorder(root, res);
return res;
}
public void inorder(TreeNode root, List<Integer> res) {
if (root == null) {
return;
}
inorder(root.left, res);
res.add(root.val);
inorder(root.right, res);
}
}
题解二 迭代
public class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
// 栈 先进后出
// 前序遍历,出栈顺序:根左右; 入栈顺序:右左根
// 中序遍历,出栈顺序:左根右; 入栈顺序:右根左
// 后序遍历,出栈顺序:左右根; 入栈顺序:根右左
List<Integer> ans = new ArrayList<Integer>();
Stack<TreeNode> stack = new Stack<>();
// root为空且stack为空,遍历结束
while (root != null || !stack.isEmpty()) {
//注意是||,只要有一个满足条件即可!
// 先根后左入栈
//不断往左子树方向走,每走一次就将当前节点保存到栈中
//这是模拟递归的调用
while (root != null) {
stack.push(root);//优先一直遍历左节点直到不能遍历为止!
root = root.left;
//当前节点为空,说明左边走到头了,从栈中弹出节点并保存
//然后转向右边节点,继续上面整个过程
}
// 此时root==null,说明上一步的root没有左子树
// 1. 执行左出栈。因为此时root==null,导致root.right一定为null
// 2. 执行下一次外层while代码块,根出栈。此时root.right可能存在
// 3a. 若root.right存在,右入栈,再出栈
// 3b. 若root.right不存在,重复步骤2
root = stack.pop();//修改根!!!
ans.add(root.val);//出栈时再记录!
root = root.right;
}
return ans;
}
}
笔记:
- 迭代的遍历用栈维护。先根节点入栈,然后左节点,最后右节点。先左边循环入,入到没有左为止,然后弹出,出值,指向右。
题解三 Morris 中序遍历
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<Integer>();
TreeNode pre = null;
while(root!=null) {
//如果左节点不为空,就将当前节点连带右子树全部挂到
//左节点的最右子树下面
if(root.left!=null) {
pre = root.left;
while(pre.right!=null) {//找到左节点的最右子树
pre = pre.right;
}
pre.right = root;
//将root指向root的left
TreeNode tmp = root;
root = root.left;
tmp.left = null;//为什么不能直接置null?
//左子树为空,则打印这个节点,并向右边遍历
} else {
res.add(root.val);
root = root.right;
}
}
return res;
}
}
笔记: