94, 二叉树的中序遍历
大约 2 分钟
一、题目描述
给定一个二叉树的根节点root
,返回它的中序遍历。
示例 1
输入: root = [1, null, 2, 3]
输出: [1, 3, 2]
示例 2
输入: root = []
输出: []
示例 3
输入: root = [1]
输出: [1]
提示
- 树中节点数目在范围
[0, 100]
内 -100 <= Node.val <= 100
进阶
递归算法很简单,你可以通过迭代算法完成吗?
相关主题
- 栈
- 树
- 深度优先搜索
- 二叉树
二、题解
#[derive(Debug, PartialEq, Eq)]
pub struct TreeNode {
pub val: i32,
pub left: Option<Rc<RefCell<TreeNode>>>,
pub right: Option<Rc<RefCell<TreeNode>>>,
}
impl TreeNode {
#[inline]
pub fn new(val: i32) -> Self {
TreeNode {
val,
left: None,
right: None,
}
}
}
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode() {}
TreeNode(int val) { this.val = val; }
TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
}
方法 1: 递归
pub fn inorder_traversal(root: Option<Rc<RefCell<TreeNode>>>) -> Vec<i32> {
let mut res = vec![];
const RECURSION_IMPL: fn(root: Option<Rc<RefCell<TreeNode>>>, res: &mut Vec<i32>) =
|root, res| match root {
None => {}
Some(root) => {
RECURSION_IMPL(root.borrow_mut().left.take(), res);
res.push(root.borrow().val);
RECURSION_IMPL(root.borrow_mut().right.take(), res);
}
};
RECURSION_IMPL(root, &mut res);
return res;
}
BiConsumer<TreeNode, List<Integer>> recursionImpl = (root, res) -> {
if (root == null) {
return;
}
this.recursionImpl.accept(root.left, res);
res.add(root.val);
this.recursionImpl.accept(root.right, res);
};
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
this.recursionImpl.accept(root, res);
return res;
}
方法 2: 迭代
pub fn inorder_traversal(root: Option<Rc<RefCell<TreeNode>>>) -> Vec<i32> {
//Self::iteration_impl_1(root)
//Self::iteration_impl_2(root)
Self::iteration_impl_3(root)
}
fn iteration_impl_1(mut root: Option<Rc<RefCell<TreeNode>>>) -> Vec<i32> {
let mut res = vec![];
let mut stack = vec![];
while root.is_some() || !stack.is_empty() {
while let Some(curr) = root {
root = curr.borrow_mut().left.take();
stack.push(curr);
}
if let Some(curr) = stack.pop() {
res.push(curr.borrow().val);
root = curr.borrow_mut().right.take();
}
}
res
}
fn iteration_impl_2(mut root: Option<Rc<RefCell<TreeNode>>>) -> Vec<i32> {
let mut res = vec![];
let mut stack = vec![];
while root.is_some() || !stack.is_empty() {
match root {
Some(curr) => {
root = curr.borrow_mut().left.take();
stack.push(curr);
}
None => {
if let Some(curr) = stack.pop() {
res.push(curr.borrow().val);
root = curr.borrow_mut().right.take();
}
}
}
}
res
}
fn iteration_impl_3(root: Option<Rc<RefCell<TreeNode>>>) -> Vec<i32> {
let mut res = vec![];
if let Some(root) = root {
let mut stack = vec![Ok(root)];
while let Some(curr) = stack.pop() {
match curr {
Ok(node) => {
if let Some(right) = node.borrow_mut().right.take() {
stack.push(Ok(right)); // Right
}
stack.push(Err(node.borrow().val)); // Root
if let Some(left) = node.borrow_mut().left.take() {
stack.push(Ok(left)); // Left
}
}
Err(val) => res.push(val),
}
}
}
res
}
public List<Integer> inorderTraversal(TreeNode root) {
//return this.iterationImpl1(root);
//return this.iterationImpl2(root);
return this.iterationImpl3(root);
}
List<Integer> iterationImpl1(TreeNode root) {
List<Integer> res = new ArrayList<>();
Deque<TreeNode> stack = new ArrayDeque<>();
while (root != null || !stack.isEmpty()) {
while (root != null) {
stack.push(root);
root = root.left;
}
TreeNode curr = stack.pop();
root = curr.right;
res.add(curr.val);
}
return res;
}
List<Integer> iterationImpl2(TreeNode root) {
List<Integer> res = new ArrayList<>();
Deque<TreeNode> stack = new ArrayDeque<>();
while (root != null || !stack.isEmpty()) {
if (root != null) {
stack.push(root);
root = root.left;
} else {
TreeNode curr = stack.pop();
root = curr.right;
res.add(curr.val);
}
}
return res;
}
List<Integer> iterationImpl3(TreeNode root) {
List<Integer> res = new ArrayList<>();
if (root != null) {
Deque<Object> stack = new ArrayDeque<>() {{
this.push(root);
}};
while (!stack.isEmpty()) {
Object curr = stack.pop();
switch (curr) {
case TreeNode node -> {
if (node.right != null) {
stack.push(node.right);
}
stack.push(node.val);
if (node.left != null) {
stack.push(node.left);
}
}
case Integer val -> res.add(val);
default -> throw new IllegalStateException("Unexpected value: " + curr);
}
}
}
return res;
}