天天刷算法之N叉树的前序遍历(简单)- js实现

456 阅读1分钟

题目

给定一个 N 叉树,返回其节点值的 前序遍历 。

N 叉树 在输入中按层序遍历进行序列化表示,每组子节点由空值 null 分隔(请参见示例)。

进阶:

递归法很简单,你可以使用迭代法完成此题吗?

image.png

题解

递归

题目所求返回值类似于二叉树的前序遍历,所以要先塞入根节点,然后从左往右,从上往下递归。

  • 递归函数的定义为:将当前节点和其子节点塞入返回数组。
  • 边界条件为:root不存在,返回空数组。
/**
 * // Definition for a Node.
 * function Node(val, children) {
 *    this.val = val;
 *    this.children = children;
 * };
 */

/**
 * @param {Node|null} root
 * @return {number[]}
 */
var preorder = function (root, arr = []) {
    if (!root) return [];
    // 将当前节点值塞入数组
    arr.push(root.val);
    
    if (root.children) {
        root.children.forEach(item => {
            preorder(item, arr);
        })
    }
    return arr;
}

迭代

题目进阶需要使用迭代,因为类似前序遍历,是深度优先遍历,所以我们使用栈(若是广度优先,使用队列)。

因为要从左至右,从上至下遍历,需要在每一层的最左边节点在栈顶,所以需要将root.children翻转,让最左边节点最后入栈。

这样最左边节点第一个出栈后会将他的子节点从右往左压入栈,然后循环往复。

/**
 * @param {Node|null} root
 * @return {number[]}
 */
var preorder = function(root) {
    if (!root) return [];
    const arr = [];
    const stack = [root];
    while(stack.length) {
        // 取栈顶节点
        const top = stack.pop();
        arr.push(top.val)
        // 若栈顶有子节点,将其子节点从右往左入栈
        if (top.children) {
            top.children.reverse().forEach(item => {
                stack.push(item)
            })            
        }
    }
    return arr;
};