1. 迭代法实现前序遍历
前序遍历是中左右, 如果还有左子树就一直向下找, 之后再从最底层逐步向上向右找。
代码实现:
public static List<Integer> preOrderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<Integer>();
if (root == null) {
return res;
}
Deque<TreeNode> stack = new LinkedList<>();
TreeNode node = root;
while (!stack.isEmpty() || node != null) {
while (node != null) {
stack.push(node);
res.add(node.val);
node = node.left;
}
node = stack.pop();
node = node.right;
}
return res;
}
2. 迭代法实现中序遍历
中序遍历是左中右, 先访问的是二叉树左子树的节点, 然后一层一层向下访问, 直到到达树底层的最左节点, 再开始处理节点。在使用迭代法写中序遍历时, 需要使用指针的遍历来帮助访问节点, 栈用来处理节点上的元素。
代码实现:
public static List<Integer> inorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<Integer>();
Deque<TreeNode> stack = new LinkedList<TreeNode>();
while (root != null || !stack.isEmpty()) {
while (root != null) {
stack.push(root);
root = root.left;
}
root = stack.pop();
res.add(root.val);
root = root.right;
}
return res;
}
3. 迭代法实现后序遍历
首先, 我们先看一下后序遍历的顺序, 如下图:
遍历后的结果为: 9 -> 15 -> 17 -> 20 -> 3; 如果我们将其整体反转的话, 得到的遍历结果为: 3 -> 20 -> 17 -> 15 -> 9。我们发现反转后的遍历结果和前序遍历思路几乎一致, 只不过左右顺序相反: 前序是先中间, 再左边然后右边, 而这里是先中间, 再右边然后左边。所以我们可以将前序遍历改造一下, 得到结果之后再反转, 最终得到后序遍历的结果。
代码实现:
public List<Integer> postOrderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
if (root == null) return res;
Stack<TreeNode> stack = new Stack<>();
TreeNode node = root;
while (!stack.isEmpty() || node != null) {
while (node != null) {
res.add(node.val);
stack.push(node);
node = node.right;
}
node = stack.pop();
node = node.left;
}
Collections.reverse(res);
return res;
}