[路飞]二叉树的层序遍历(迭代 + 递归)

770 阅读2分钟

二叉树的层序遍历: 横向一层层的去输出

tmp.001.jpeg

如图 我们输出的是:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

按照Leetcode里需要打出

[
  [1],
  [2, 3],
  [4, 5, 6],
  [7, 8, 9, 10]
]

只是获取输出的方式不同

迭代 - 广度优先

动画演示

测序遍历-迭代.g.gif

文字解析

  1. 先用栈把第一层入栈
  2. 循环把栈中节点逐个输出,如果存在子节点,子节点入下一层的栈
  3. 当当前栈中的节点都输出了, 把下一层的栈替换当前层的栈
  4. 依次输出当当前层的栈中没有任何节点的时候 输出完成

代码

function levelorder(root) {
    // 空节点的情况不能忘记了😭
    if(root === null) return []
    // 输出结果
    const res = []
    // 先入栈第一层
    let stack = [root]
    
    // 循环终止条件:栈中没有节点
    while(stack.length) {
        // 循环依次输出我们的节点
        // 这里我们输出按照LeetCode的结果, 每一层一个数组
        const level = []
        // 需要下一层的栈保存我们下一层的节点
        const nextLevelNodes = []
        for (let i = 0; i < stack.length; i++) {
            level.push(stack[i].val)
            if(stack[i].left) nextLevelNodes.push(stack[i].left)
            if(stack[i].right) nextLevelNodes.push(stack[i].right)
        }
        // 输出到我们的结果中
        res.push(level)
        // 当前层输出结束,我们把下一层变成当前层
        stack = nextLevelNodes
    }
    
    return res
}

看下官方题解

思路一直,整体的处理细节不太一样

递归 - 深度优先

动画演示

层序遍历-递归.gif

文字解析

  1. 通过层数index 来对 结果res 塞入遍历到的节点
  2. 每次遍历index + 1 对子节点在遍历,先遍历到最左侧的节点,然后一次如图遍历

代码

var levelOrder = function(root) {
    // 空节点
    if (root === null) return []
    // 定义输出结果
    let res = []
    // 递归遍历,传根节点,层数:开始是第1层,输出结果存起来
    dfs(root, 1, res)
    return res
};

function dfs(root, index, res) {
    // 第一次深度遍历时候,先加上一个空数组
    if (res.length < index) {
        res.push([])
    }
    // 然后把第index层 结果的第index - 1项push val
    res[index - 1].push(root.val)
    // 对子节点递归遍历 层数加1
    if (root.left) dfs(root.left, index + 1, res)
    if (root.right) dfs(root.right, index + 1, res)
}

总结

  • 深度搜索,广度搜索应用区分,灵活使用层级index