描述
给定一棵二叉树,分别按照二叉树先序,中序和后序打印所有的节点。
数据范围:0 \le n \le 10000≤n≤1000,树上每个节点的val值满足 0 \le val \le 1000≤val≤100
要求:空间复杂度 O(n)O(n),时间复杂度 O(n)O(n)
样例解释:
如图二叉树结构
示例1
输入:{1,2,3}
返回值:[[1,2,3],[2,1,3],[2,3,1]]
说明:如题面图
示例2
输入:{}
返回值: [[],[],[]]
解题思路
1.使用递归的话,解题会非常简单,但是得是面试官同意的情况下
public class Solution {
private List<Integer> preList = new ArrayList<>();
private List<Integer> midList = new ArrayList<>();
private List<Integer> postList = new ArrayList<>();
public static void main(String[] args) {
Solution solution = new Solution();
TreeNode root = new TreeNode(1);
root.left = new TreeNode(2);
root.right = new TreeNode(3);
int[][] res = solution.threeOrders(root);
for (int i = 0; i < res.length; i++) {
for (int j = 0; j < res[0].length; j++) {
System.out.print(res[i][j] + " ");
}
System.out.println();
}
}
public int[][] threeOrders(TreeNode root) {
// write code here
//先序遍历
preOrder(root);
//中序遍历
midOrder(root);
//后序遍历
postOrder(root);
int[][] res = new int[3][preList.size()];
for (int i = 0; i < preList.size(); i++) {
res[0][i] = preList.get(i);
res[1][i] = midList.get(i);
res[2][i] = postList.get(i);
}
return res;
}
private void preOrder(TreeNode root) {
if (root != null) {
preList.add(root.val);
preOrder(root.left);
preOrder(root.right);
}
}
private void midOrder(TreeNode root) {
if (root != null) {
midOrder(root.left);
midList.add(root.val);
midOrder(root.right);
}
}
private void postOrder(TreeNode root) {
if (root != null) {
postOrder(root.left);
postOrder(root.right);
postList.add(root.val);
}
}
}
2.非递归的形式,用栈的方式实现前中后序排序
- 这里的后续遍历非常关键,有诀窍~!!
- 后续遍历可以看成先序的改版(根右左)的reverse反转!
import java.util.*;
class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
public class Solution {
private List<Integer> preList = new ArrayList<>();
private List<Integer> midList = new ArrayList<>();
private List<Integer> postList = new ArrayList<>();
public static void main(String[] args) {
Solution solution = new Solution();
TreeNode root = new TreeNode(1);
root.left = new TreeNode(2);
root.right = new TreeNode(3);
int[][] res = solution.threeOrders(root);
for (int i = 0; i < res.length; i++) {
for (int j = 0; j < res[0].length; j++) {
System.out.print(res[i][j] + " ");
}
System.out.println();
}
}
public int[][] threeOrders(TreeNode root) {
// write code here
//先序遍历
preOrder(root);
//中序遍历
midOrder(root);
//后序遍历
postOrder(root);
int[][] res = new int[3][preList.size()];
for (int i = 0; i < preList.size(); i++) {
res[0][i] = preList.get(i);
res[1][i] = midList.get(i);
res[2][i] = postList.get(i);
}
return res;
}
private void preOrder(TreeNode root) {
Stack<TreeNode> stack = new Stack<>();
while (root != null || !stack.isEmpty()) {
while (root!=null){
preList.add(root.val);
stack.add(root);
root = root.left;
}
if (!stack.isEmpty()){
root = stack.pop();
root = root.right;
}
}
}
private void midOrder(TreeNode root) {
Stack<TreeNode> stack = new Stack<>();
while (root != null || !stack.isEmpty()) {
while (root!=null){
stack.add(root);
root = root.left;
}
if (!stack.isEmpty()){
root = stack.pop();
midList.add(root.val);
root = root.right;
}
}
}
// 直接用前序遍历进行改版,先根,再右,最后左,记得在最后reverse就是后续!
private void postOrder(TreeNode root){
Stack<TreeNode> stack = new Stack<>();
while (root != null || !stack.isEmpty()) {
while (root!=null){
postList.add(root.val);
stack.add(root);
root = root.right;
}
if (!stack.isEmpty()){
root = stack.pop();
root = root.left;
}
}
Collections.reverse(postList);
}
}