力扣深度优先搜索练习题(二叉树的前序遍历、二叉树的后序遍历)

60 阅读2分钟

二叉树的前序遍历

来源:力扣(LeetCode) 链接:leetcode.cn/problems/bi…

给你二叉树的根节点 root ,返回它节点值的 前序 遍历。

示例 1:

图片.png

输入:root = [1,null,2,3]

输出:[1,2,3]

示例 2:

输入:root = []

输出:[]

示例 3:

输入:root = [1]

输出:[1]

示例 4:

图片.png

输入:root = [1,2]

输出:[1,2]

示例 5:

图片.png

输入:root = [1,null,2]

输出:[1,2]

提示:

  • 树中节点数目在范围 [0, 100] 内
  • -100 <= Node.val <= 100

进阶:递归算法很简单,你可以通过迭代算法完成吗?

代码

class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        if (root == null) {
            return result;
        }
        Stack<TreeNode> stack = new Stack<>();
        stack.push(root);
        while (!stack.isEmpty()) {
            TreeNode node = stack.pop();
            result.add(node.val);
            if (node.right != null) {
                stack.push(node.right);
            }
            if (node.left != null) {
                stack.push(node.left);
            }
        }
        return result;
    }
}

思路分析

  1. 创建一个空的结果列表result,用于存储遍历结果。

  2. 若根节点root为空,直接返回结果列表result

  3. 创建一个栈stack,将根节点root入栈。

  4. 当栈不为空时,执行以下操作:

    • 弹出栈顶节点,记为node,将node的值添加到结果列表result中。
    • node的右子节点不为空,将右子节点入栈。
    • node的左子节点不为空,将左子节点入栈。
  5. 返回结果列表result

二叉树的后序遍历

来源:力扣(LeetCode) 链接:leetcode.cn/problems/bi…

给你一棵二叉树的根节点 root ,返回其节点值的 后序遍历 。

示例 1:

图片.png

输入:root = [1,null,2,3]

输出:[3,2,1]

示例 2:

输入:root = []

输出:[]

示例 3:

输入:root = [1]

输出:[1]

提示:

  • 树中节点的数目在范围 [0, 100] 内
  • -100 <= Node.val <= 100

进阶:递归算法很简单,你可以通过迭代算法完成吗?

代码

class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        if (root == null) {
            return result;
        }
        Stack<TreeNode> stack = new Stack<>();
        stack.push(root);
        TreeNode prev = null;
        while (!stack.isEmpty()) {
            TreeNode curr = stack.peek();
            if (prev == null || prev.left == curr || prev.right == curr) {
                if (curr.left != null) {
                    stack.push(curr.left);
                } else if (curr.right != null) {
                    stack.push(curr.right);
                } else {
                    result.add(curr.val);
                    stack.pop();
                }
            } else if (curr.left == prev) {
                if (curr.right != null) {
                    stack.push(curr.right);
                } else {
                    result.add(curr.val);
                    stack.pop();
                }
            } else if (curr.right == prev) {
                result.add(curr.val);
                stack.pop();
            }
            prev = curr;
        }
        return result;
    }
}

思路分析

  1. 创建一个空的结果列表result,用于存储遍历结果。

  2. 若根节点root为空,直接返回结果列表result

  3. 创建一个栈stack,将根节点root入栈。

  4. 创建一个辅助节点prev,初始值为null,用于记录上一次访问的节点。

  5. 当栈不为空时,执行以下操作:

    • 获取栈顶节点,记为curr

    • 根据prevcurr的关系,判断下一步的操作:

      • prevnull或者prevcurr的父节点(即从上往下遍历):

        • curr有左子节点,将左子节点入栈。
        • curr没有左子节点,但有右子节点,将右子节点入栈。
        • curr既没有左子节点也没有右子节点,说明已经到达叶子节点,将curr的值添加到结果列表result中,并将curr出栈。
      • prevcurr的左子节点(即从左子节点返回到根节点):

        • curr有右子节点,将右子节点入栈。
        • curr没有右子节点,说明已经遍历完curr的左右子节点,将curr的值添加到结果列表result中,并将curr出栈。
      • prevcurr的右子节点(即从右子节点返回到根节点):

        • curr的值添加到结果列表result中,并将curr出栈。
    • 更新prevcurr