「前端刷题」144.二叉树的前序遍历(EASY)

114 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第24天,点击查看活动详情

题目(Binary Tree Preorder Traversal)

链接:https://leetcode-cn.com/problems/binary-tree-preorder-traversal
解决数:2498
通过率:71%
标签:栈 树 深度优先搜索 二叉树 
相关公司:bytedance amazon microsoft 

给你二叉树的根节点 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

 

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

思路

前序遍历的定义:对每个节点,都是先处理当前节点,对它执行我们的处理逻辑,再递归它的左子树,再递归它的右子树,对子树中的节点执行相同的逻辑。

代码

const preorderTraversal = (root) => {
  const res = [];
  const preOrder = (root) => {
    if (root == null) return;
    res.push(root.val);
    preOrder(root.left);
    preOrder(root.right);
  };
  preOrder(root);
  return res;
}
func preorderTraversal(root *TreeNode) []int {
	res := []int{}
	var preOrder func(*TreeNode)
	preOrder = func(root *TreeNode) {
		if root == nil {
			return
		}
		res = append(res, root.Val)
		preOrder(root.Left)
		preOrder(root.Right)
	}
	preOrder(root)
	return res
}

迭代版

维护一个栈 stack,模拟递归的压栈出栈。 比照递归DFS,我们首先让左子节点尽可能地压入栈:

while (root) {
    res.push(root.val);
    if (root.right) stack.push(root.right);
    root = root.left;
}

循环结束时,栈顶的节点是位于树底部最左的一个左子节点,让它出栈,带出它的右子节点入栈(如果有)。

并且这个右子节点,也要重复前面的逻辑『让左节点尽可能的压入栈』,可以看到这部分代码重复了两次:

while (stack.length) {
    root = stack.pop();
    res.push(root.val);
    if (root.right) stack.push(root.right);
    root = root.left;
    while (root) {
        res.push(root.val);
        if (root.right) stack.push(root.right);
        root = root.left;
    }
}

没有了左节点可入栈,就取出栈顶的节点,重复上面的操作,栈中节点的出栈,“牵扯”出所有的右子树,从而遍历了整个树。

我们知道,前序遍历是在递归左子树和递归右子树之前,处理当前节点,对迭代版来说,就是压栈之前做事——把节点值推入 res 数组。

代码

const preorderTraversal = (root) => {
  const res = [];
  const stack = [];
  while (root) {
    res.push(root.val);
    if (root.right) stack.push(root.right);
    root = root.left;
  }

  while (stack.length) {
    root = stack.pop();
    res.push(root.val);
    if (root.right) stack.push(root.right);
    root = root.left;
    while (root) {
      res.push(root.val);
      if (root.right) stack.push(root.right);
      root = root.left;
    }
  }

  return res;
};