94 | 二叉树的中序遍历 |
---|---|
144 | 二叉树的前序遍历 |
145 | 二叉树的后序遍历 |
迭代实现,迭代实现,非递归,非递归。
1. 前序遍历
// 前序遍历 迭代
public List<Integer> preorderTraversal(TreeNode root) {
Stack<TreeNode> stack = new Stack<>();
List<Integer> res = new ArrayList<>();
while (root != null || !stack.isEmpty()) {
// 先存到列表中,然后不断的向左子树走
if (root != null) {
res.add(root.val);
stack.add(root);
root = root.left;
} else {
// 当节点为空时,说明左边走到头了,从栈中弹出一个元素
// 然后转向右子节点,继续执行上面的步骤
TreeNode temp = stack.pop();
root = temp.right;
}
}
return res;
}
2. 中序遍历
// 中序遍历 迭代
public List<Integer> inorderTraversal(TreeNode root) {
Stack<TreeNode> stack = new Stack<>();
List<Integer> res = new ArrayList<>();
while (root != null || stack.size()>0 ) {
// 不断往左子树方向走,没走一次将当前节点保存到栈中
if (root != null) {
stack.add(root);
root = root.left;
} else {
// 当节点为空,说明左边走到头了,从栈中弹出节点并保存
// 然后转向右边节点,继续上面的过程
TreeNode temp = stack.pop();
res.add(temp.val);
root = temp.right;
}
}
return res;
}
3. 后序遍历
后序遍历迭代实现关键点在于怎么判断右节点已经被访问过了,所以增加一个指针 prev
指向上一个被访问的节点。
// 后序遍历 迭代
// 后序遍历 迭代
public List<Integer> postorderTraversal(TreeNode root) {
Stack<TreeNode> stack = new Stack<>();
List<Integer> res = new ArrayList<>();
if(root == null) return res;
TreeNode prev = null; // 指向上一个被访问的节点
while(root != null || !stack.isEmpty()) {
// 不断的向左子树走,每走一次将当前节点保存到栈中
if (root != null) {
stack.push(root);
root = root.left;
} else {
// 当前节点为空,说明左子树走到头了,从栈中弹出一个节点
// 判断该节点是否为叶子节点 或者 是右子树已经访问过的节点
root = stack.pop();
if (root.right == null || root.right == prev) {
res.add(root.val);
prev = root;
root = null;
} else {
// 该节点不是叶子节点,也不是右子树访问过的节点
// 将该节点继续入栈,然后转向该节点的右子节点,继续上面的过程
stack.push(root);
root = root.right;
}
}
}
return res;
}