LeetCode144、 二叉树的前序遍历

83 阅读2分钟

LeetCode 系列记录我学习算法的过程。

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第23天,点击查看活动详情

题目

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

示例:

image.png

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

image.png

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

提示:

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

思路

二叉树常见的三种遍历方式分别是先序、中序和后序遍历,先序遍历的特点就是先遍历根结点的值,再遍历左子树,最后右子树

image.png

例如上图,先序遍历得到的结果是: 1 2 4 6 7 8 3 5

知道规律后就不难解决了,也是用递归的方式来实现:

  • 首先判断根结点是否存在,不存在则直接返回空数组
  • 根结点存在则定义一个数组存储结果,将根结点值存入其中
  • 然后判断左子树是否存在,存在则递归左子树
  • 将左子树递归后的结果与初始结果合并
  • 然后判断右子树是否存在,存在则递归右子树
  • 将递归后的结果与之前的结果合并
  • 最后将结果返回即可

代码实现

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 * this.val = (val===undefined ? 0 : val)
 * this.left = (left===undefined ? null : left)
 * this.right = (right===undefined ? null : right)
 * }
 */

/**
 * @param {TreeNode} root
 * @return {number[]}
 */

var preorderTraversal = function(root) {
    // 如果当前根结点不存在,返回空数组
    if (!root) return []
    // 根结点存在则将其值存入数组
    let arr = [root.val]
    // 如果左子树存在,则递归左子树,将结果与递归后的值合并
    if (root.left) {
        arr = [...arr, ...preorderTraversal(root.left)]
    }
    // 右子树存在同上操作
    if (root.right) {
        arr = [...arr, ...preorderTraversal(root.right)]
    }
    // 最后返回结果
    return arr
};

image.png

优化

递归是最简单的实现方式,这个题目还可以用栈和迭代的方式来实现

var preorderTraversal = function(root, res = []) {
    const stack = [];
    if (root) stack.push(root);
    while(stack.length) {
        const node = stack.pop();
        if(!node) {
            res.push(stack.pop().val);
            continue;
        }
        if (node.right) stack.push(node.right); // 右
        if (node.left) stack.push(node.left); // 左
        stack.push(node); // 中
        stack.push(null);
    }; 
    return res;
};

image.png