94. 二叉树的中序遍历
深度优先搜索
class Solution {
List list = new LinkedList();
public List<Integer> inorderTraversal(TreeNode root) {
if (root == null){
return list;
}
inorderTraversal(root.left);
list.add(root.val);
inorderTraversal(root.right);
return list;
}
}
/**
* 时间复杂度 O(n)
* 空间复杂度 O(n)
*/
迭代
中序遍历的顺序是左中右,先访问的是中间节点,然后一层一层向下访问,直到到达树左边最底部,再开始处理左节点,这就造成了处理顺序和访问顺序是不一致的
因此中序遍历需要借助指针的遍历来帮助访问节点,栈则用来处理节点上的元素
class Solution {
List list = new ArrayList();
public List<Integer> inorderTraversal(TreeNode root) {
if (root == null){
return list;
}
Stack<TreeNode> stack = new Stack<>();
TreeNode cur = root;
while (cur != null || !stack.isEmpty()){
/**
* 中序遍历第一个打印的节点是最左边的叶子节点
* 如果根节点不为空,cur指针循环遍历左子树,直到最左边的叶子节点,期间将访问到的节点全部放入栈中,但是不处理
* 当cur为空时,所有的中、左节点都已经被放入栈中了,这时依次弹出左、中节点,顺便让cur指向右节点(如果右节点存在就会放入栈中,当前节点遍历完成;不存在就接着遍历上一个节点)
*/
if (cur != null) {
stack.push(cur);
cur = cur.left;
}
else {
/**
* 按照栈里的顺序弹出左、中节点,顺便判断右孩子是否存在
*/
cur = stack.pop();
list.add(cur.val);
cur = cur.right;
}
}
return list;
}
}
/**
* 时间复杂度 O(n)
* 空间复杂度 O(n)
*/
统一迭代写法
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
class Solution {
List<Integer> list = new ArrayList<>();
public List<Integer> inorderTraversal(TreeNode root) {
if (root == null){
return list;
}
Stack<Command> stack = new Stack<>();
/**
* 首先压入根节点,但不进行打印
*/
stack.push(new Command(false, root));
while (!stack.isEmpty()){
/**
* 每次弹出栈顶节点进行判断
* 如果是上一轮的根节点,就打印;否则按不同顺序压入其左右孩子和本身
*/
Command command = stack.pop();
if (command.isPrint){
list.add(command.node.val);
}
else {
/**
* 中序遍历
* 先将右孩子压入栈,然后压入根节点,最后将左孩子压入栈,让弹出的顺序变为左孩子、根节点、右孩子
* 其中根节点的isPrint == true
*/
if (command.node.right != null){
stack.push(new Command(false, command.node.right));
}
stack.push(new Command(true, command.node));
if (command.node.left != null){
stack.push(new Command(false, command.node.left));
}
}
}
return list;
}
}
/**
* 为了像递归写法一样统一前中后序遍历,将压入栈的元素定义为一个Command类
* 其中包含要处理的当前节点,还有要进行的操作
* isPrint == true代表将当前节点的值打印出来,添加进列表,否则就遍历到其左右孩子
*/
class Command{
Boolean isPrint;
TreeNode node;
Command(Boolean isPrint, TreeNode node){
this.isPrint = isPrint;
this.node = node;
}
}
/**
* 时间复杂度 O(n)
* 空间复杂度 O(n)
*/
https://leetcode-cn.com/problems/binary-tree-inorder-traversal/