问题背景
给定一个二叉树的根节点 r o o t root root,返回 它的 中序 遍历 。
数据约束
- 树中节点数目在范围 [ 0 , 100 ] [0, 100] [0,100] 内
- − 100 ≤ N o d e . v a l ≤ 100 -100 \le Node.val \le 100 −100≤Node.val≤100
解题过程
中序遍历,二叉树的基本操作。
递归的方法是先递归左子树,访问当前节点,然后访问右子树即可。
非递归的方法是在左子树非空的情况下,不断地往左子树遍历,沿途用栈来记录节点。一旦左子树为空,那么应当访问当前栈中的第一个节点,接下来处理右子树。
二叉树的遍历,递归与非递归的写法时空复杂度差异不大。一般来说,只要递归的做法能解决问题,就不必特意实现非递归的方式。
具体实现
递归
/*** Definition for a binary tree node.* 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;* }* }*/
class Solution {public List<Integer> inorderTraversal(TreeNode root) {List<Integer> res = new ArrayList<>();inorder(root, res);return res;}// 原方法要返回一个列表,不方便递归操作,重新定义一个方法来实现private void inorder(TreeNode root, List<Integer> list) {// 递归边界是当前节点为空,直接返回if(root == null) {return;}inorder(root.left, list); // 递归遍历左子树list.add(root.val); // 访问当前节点inorder(root.right, list); // 递归遍历右子树}
}
非递归
/*** Definition for a binary tree node.* 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;* }* }*/
class Solution {public List<Integer> inorderTraversal(TreeNode root) {List<Integer> res = new ArrayList<>();Stack<TreeNode> stack = new Stack<>();// 只要左子树不为空,就不断地往左子树遍历while (!stack.isEmpty() || root != null) {if (root != null) {stack.push(root); // 沿途节点进栈root = root.left; // 工作指针指向左子树} else {root = stack.pop(); res.add(root.val); // 访问栈中的第一个节点root = root.right; // 工作指针指向右子树}}return res;}
}