144. 二叉树的前序遍历

33 阅读2分钟

递归解法比较简单,此处不再赘述。仅讨论迭代解法。

private List<Integer> preorderTraversal(TreeNode root) {
    List<Integer> res = new ArrayList<>();
    if (root == null) return res;
    res.add(root.val);
    res.addAll(preorderTraversal(root.left));
    res.addAll(preorderTraversal(root.right));
    return res;
}

二叉树的前序遍历.png

  1. 如图所示,红色箭头P表示当前树节点;stack表示操作栈;result表示要返回的结果集
  2. 遍历开始:
    1. 指针P指向1节点,由于1非空,1入结果集,1入栈([1]),指针指向1的左子节点2

    2. 指针P指向2节点,由于2非空,2入结果集,2入栈([1,2]),指针指向2的左子节点4

    3. 指针P指向4节点,由于4非空,4入结果集,4入栈([1,2,4]),指针指向4的左子节点4l(null)

    4. 指针P指向4l节点,由于4l为空,4出栈([1,2]),指针指向4的右子节点4r(null)

    5. 指针P指向4r节点,由于4r为空,2出栈([1]),指针指向2的右子节点5

    6. 指针P指向5节点,由于5非空,5入结果集,5入栈([1,5]),指针指向5的左子节点5l(null)

    7. 指针P指向5l节点,由于5l为空,5出栈([1]),指针指向5的右子节点5r(null)

    8. 指针P指向5r节点,由于5r为空,1出栈([]),指针指向1的右子节点3

    9. 指针P指向3节点,由于3非空,3入结果集,3入栈([3]),指针指向3的左子节点6

    10. 指针P指向6节点,由于6非空,6入结果集,6入栈([3,6]),指针指向6的左子节点6l(null)

    11. 指针P指向6l节点,由于6l为空,6出栈([3]),指针指向6的右子节点6r(null)

    12. 指针P指向6r节点,由于6r为空,3出栈(),指针指向3的右子节点7

    13. 指针P指向7节点,由于7非空,7入结果集,7入栈([7]),指针指向7的左子节点7l(null)

    14. 指针P指向7l节点,由于7l为空,7出栈([]),指针指向7的右子节点7r(null)

    15. 指针P指向7r节点,此时当前节点7r为空,stack也为空,循环结束,二叉树遍历完成。

private List<Integer> preorderTraversal(TreeNode root) {
    List<Integer> res = new ArrayList<>();
    Stack<TreeNode> stack = new Stack<>();
    while (root != null || !stack.isEmpty()) {
        if (root == null) {
            TreeNode pop = stack.pop();
            root = pop.right;
        } else {
            res.add(root.val);
            stack.push(root);
            root = root.left;
        }
    }
    return res;
}