LeetCode探索(21):144-二叉树的前序遍历

159 阅读2分钟

「这是我参与2022首次更文挑战的第7天,活动详情查看:2022首次更文挑战」。

题目

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

示例 1:

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

示例 2:

输入:root = []
输出:[]

示例 3:

输入:root = [1]
输出:[1]

示例 4:

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

示例 5:

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

提示:

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

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

思考

二叉树(Binary tree)是树形结构的一个重要类型,其特点是每个结点最多只能有两棵子树,且有左右之分。许多实际问题抽象出来的数据结构往往是二叉树形式,即使是一般的树也能简单地转换为二叉树,而且二叉树的存储结构及其算法都较为简单,因此二叉树显得特别重要。

二叉树的遍历是指不重复地访问二叉树中所有结点。二叉树的前序遍历的特点是,首先是访问根结点,接着是左子树,最后是右子树,依次类推。

我们可以使用递归的方法来进行二叉树的前序遍历。首先是访问根结点,接着将根节点的左子树进行递归遍历,然后是右子树进行递归。每次遍历都在res中存入当前结点的值。

我们也可以使用迭代的方法来进行二叉树的前序遍历。在stack中依次存入每个根结点,当根结点为true时在res中存入当前结点的值,并遍历左子树。在最后一个左子树为null时,取出对应的右子树进行遍历。最终结果是res

解答

方法一:递归

var preorderTraversal = function(root, res = []) {
  if (!root) return res
  res.push(root.val)
  preorderTraversal(root.left, res)
  preorderTraversal(root.right, res)
  return res
}

复杂度分析

  • 时间复杂度:O(n),其中 n 是结点个数。可以使用 Master公式 分析。

  • 空间复杂度:O(n),即树的高度,最坏情况下递归调用的深度为O(n),平均空间复杂度O(logn)。

方法二:迭代

var preorderTraversal = function (root) {
  let res = [], stack = []
  while (stack.length || root) {
    while (root) {
      res.push(root.val)
      stack.push(root) // stack中存入每个根结点
      root = root.left
    }
    // 最后一个左子树为null时,取出对应的右子树进行遍历
    root = stack.pop() // 删除并返回数组的最后一个元素
    root = root.right
  }
  return res
}

复杂度分析

  • 时间复杂度:O(n),其中 n 是结点个数。

  • 空间复杂度:O(n)

参考