LeetCode:二叉树的前序遍历

1、题目描述

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

示例 1:

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

输出:[1,2,3]

解释:

示例 2:

输入:root = [1,2,3,4,5,null,8,null,null,6,7,9]

输出:[1,2,4,5,6,7,3,8,9]

解释:

示例 3:

输入:root = []

输出:[]

示例 4:

输入:root = [1]

输出:[1]

提示:

  • 树中节点数目在范围 [0, 100] 内

  • -100 <= Node.val <= 100

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

2、方法1:迭代法

解题思路

迭代法通过显式地使用栈来模拟递归的隐式栈调用,避免了递归可能导致的栈溢出问题。

步骤:

  1. 初始化:创建一个空栈和一个空列表用于存储遍历结果。从根节点开始遍历。

  2. 访问节点并遍历左子树

    • 访问当前节点(将节点值加入结果列表)。

    • 将当前节点压入栈中(以便后续回溯)。

    • 转向当前节点的左子节点,重复上述过程。

  3. 回溯并遍历右子树

    • 当左子节点为空时,弹出栈顶节点(回溯到父节点)。

    • 转向该节点的右子节点,重复上述过程。

  4. 终止条件:当栈为空且当前节点为空时,遍历结束。

时间复杂度:O(n),空间复杂度:O(n)(栈空间)

public List<Integer> preorderTraversal(TreeNode root) {
    List<Integer> list = new ArrayList<>();
    Stack<TreeNode> stack = new Stack<>();
    TreeNode curNode = root;
    while (curNode != null || !stack.isEmpty()) {
        // 访问节点并遍历左子树
        while (curNode != null) {
            list.add(curNode.val);  // 访问当前节点
            stack.push(curNode);    // 压栈以便回溯
            curNode = curNode.left; // 转向左子节点
        }
        // 回溯并转向右子树
        curNode = stack.pop();      // 弹出栈顶节点(父节点)
        curNode = curNode.right;    // 转向右子节点
    }
    return list;
}

3、方法2:递归

解题思路

递归法直接利用函数的调用栈来实现前序遍历,代码简洁但可能因递归深度过大导致栈溢出。

步骤:

  1. 递归终止条件:当前节点为空时,直接返回。

  2. 访问节点:将当前节点的值加入结果列表。

  3. 递归左子树:对当前节点的左子节点调用递归函数。

  4. 递归右子树:对当前节点的右子节点调用递归函数。

时间复杂度:O(n),空间复杂度:O(n)(调用栈)

public List<Integer> preorderTraversal(TreeNode root) {
    List<Integer> list = new ArrayList<>();
    preTree(root, list);
    return list;
}

public void preTree(TreeNode node, List list) {
    if (node == null) return;
    list.add(node.val);          // 访问当前节点
    preTree(node.left, list);    // 递归左子树
    preTree(node.right, list);   // 递归右子树
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值