LeetCode 第 94 题:“二叉树的中序遍历”题解
题解地址:模拟系统栈完成非递归中序遍历,同理可以完成非递归的前序遍历和后序遍历(Python 代码、Java 代码)。
说明:文本首发在力扣的题解版块,更新也会在第 1 时间在上面的网站中更新,这篇文章只是上面的文章的一个快照,您可以点击上面的链接看到其他网友对本文的评论。
传送门:94. 二叉树的中序遍历。
给定一个二叉树,返回它的中序 遍历。
示例:
输入: [1,null,2,3] 1
2 / 3输出: [1,3,2] 进阶: 递归算法很简单,你可以通过迭代算法完成吗?
模拟系统栈完成非递归中序遍历,同理可以完成非递归的前序遍历和后序遍历(Python 代码、Java 代码)
方法:模拟系统栈
模拟系统栈的方法其实并不难理解,就是在栈中放入结点的同时,同时传入一个指令,这个指令可以有 2 个含义:
1、递归执行(就是继续放入栈里);
2、马上执行。
模拟系统栈的注意事项:因为栈是先进后出的,当递归执行的时候,代码编写的顺序应该是相应遍历种类的倒序(具体可以参考下面的代码)。
模拟系统栈的好处:稍微改动一下代码,就可以完成非递归的前序遍历和后序遍历。
参考代码:
Python 代码:
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class Solution:
def inorderTraversal(self, root: TreeNode) -> List[int]:
if not root:
return []
# 1 表示递归处理
stack = [(1, root)]
res = []
while stack:
command, node = stack.pop()
if command == 0:
# 0 表示当前马上执行将结点的值添加到结果集中
res.append(node.val)
else:
# 关键在这里:因为是模拟系统栈,应该把中序遍历的顺序倒过来写
# 调整一下顺序就可以完成前序遍历和后序遍历
if node.right:
stack.append((1, node.right))
stack.append((0, node))
if node.left:
stack.append((1, node.left))
return res
Java 代码:
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) {
val = x;
}
}
public class Solution {
private enum Action {
// GO 表示递归处理
// ADDTORESULT 表示当前马上执行将结点的值添加到结果集中
GO, ADDTORESULT
}
private class Command {
private Action action;
private TreeNode node;
public Command(Action action, TreeNode node) {
this.action = action;
this.node = node;
}
}
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
if (root == null) {
return res;
}
Stack<Command> stack = new Stack<>();
stack.add(new Command(Action.GO, root));
while (!stack.isEmpty()) {
Command command = stack.pop();
if (command.action == Action.ADDTORESULT) {
res.add(command.node.val);
} else {
assert command.action == Action.GO;
// 关键在这里:因为是模拟系统栈,应该把中序遍历的顺序倒过来写
// 调整一下顺序就可以完成前序遍历和后序遍历
if (command.node.right != null) {
stack.add(new Command(Action.GO, command.node.right));
}
stack.add(new Command(Action.ADDTORESULT, command.node));
if (command.node.left != null) {
stack.add(new Command(Action.GO, command.node.left));
}
}
}
return res;
}
}