0. 整体思路
用非递归的方法解决二叉树的三种遍历问题,主要思想其实就是利用了 【栈】 ,将暂时用不到的TreeNode节点存起来,先沿着某一分支(left或者right)走下去,等到了叶子节点(root==null)时再依次pop出来赋给root。
二叉树结点TreeNode的定义:
/**
* 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;
}
}
1. 二叉树的前序遍历(非递归)
/**
* Binary tree preorder traversal.
*/
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList<>();
Deque<TreeNode> stack = new ArrayDeque<>();
while (root != null || !stack.isEmpty()) {
// 先存入当前节点的val,再沿着左子树遍历
if (root != null) {
list.add(root.val);
stack.push(root);
root = root.left;
} else {
// 遍历到头了则回溯,取上一个节点的右子树
TreeNode temp = stack.pop();
root = temp.right;
}
}
return list;
}
}
2. 二叉树的中序遍历(非递归)
/**
* Binary tree inordertraversal.
*/
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList<>();
Deque<TreeNode> stack = new ArrayDeque<>();
while (root != null || !stack.isEmpty()) {
// 不存入val,先沿着左子树遍历
if (root != null) {
stack.push(root);
root = root.left;
} else {
// 到叶子节点了,存入val,再利用stack回溯到上一个节点,取其右子树作为root
TreeNode temp = stack.pop();
list.add(temp.val);
root = temp.right;
}
}
return list;
}
}
3. 二叉树的后序遍历(非递归)
后序遍历其实跟前序遍历非常像,不同点在于:
- 每次存入 list 时,都不是插入到末尾,而是用
list.add(0,root.val)
插入到 list 的最前面。 - 按照我们每次都插到最开头的做法,那么就要先遍历右子树,再遍历左子树了。
/**
* Binary tree postorder traversal.
*/
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList<>();
Deque<TreeNode> stack = new ArrayDeque<>();
while (root != null || !stack.isEmpty()) {
// 插入到list的最前方,然后先遍历右子树
if (root != null) {
list.add(0, root.val);
stack.push(root);
root = root.right;
} else {
// 再用栈进行回溯,遍历左子树
TreeNode temp = stack.pop();
root = temp.left;
}
}
return list;
}
}