风格统一的三种非递归方式遍历二叉树,方便记忆和理解↓
import java.util.ArrayList;
import java.util.Deque;
import java.util.LinkedList;
import java.util.List;
public class Traversal {
class TreeNode {
int val;
TreeNode left;
TreeNode right;
public TreeNode() {
}
public TreeNode(int val) {
this.val = val;
}
public TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
}
/**
* 非递归先序遍历
*/
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
if (root == null) {
return res;
}
Deque<TreeNode> stk = new LinkedList<>();
while (root != null || !stk.isEmpty()) {
while (root != null) {
res.add(root.val);
stk.push(root);
root = root.left;
}
root = stk.pop();
root = root.right;
}
return res;
}
/**
* 非递归中序遍历
*/
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
if (root == null) {
return res;
}
Deque<TreeNode> stk = new LinkedList<>();
while (root != null || !stk.isEmpty()) {
while (root != null) {
stk.push(root);
root = root.left;
}
root = stk.pop();
res.add(root.val);
root = root.right;
}
return res;
}
/**
* 非递归后序遍历
*/
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
if (root == null) {
return res;
}
Deque<TreeNode> stk = new LinkedList<>();
TreeNode prev = null;
while (root != null || !stk.isEmpty()) {
//1.遍历到最左子节点
while (root != null) {
stk.push(root);
root = root.left;
}
//从栈中弹出的元素,左子树一定是访问完了的。
root = stk.pop();
//现在需要确定 是否有右子树 或 已经访问过右子树
//如果没有右子树,或者右子树访问完了,也就是上一个访问的节点是右子节点时
//说明可以访问当前节点
if (root.right == null || root.right == prev) {
res.add(root.val);
//防止重复访问右子树
prev = root;
//防止重复访问左子树
root = null;
} else {
//如果右子树没有被访问,那么将当前节点压栈,访问右子树
stk.push(root);
root = root.right;
}
}
return res;
}
}