二叉树的层序遍历: 横向一层层的去输出
如图 我们输出的是:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
按照Leetcode里需要打出
[
[1],
[2, 3],
[4, 5, 6],
[7, 8, 9, 10]
]
只是获取输出的方式不同
迭代 - 广度优先
动画演示
文字解析
- 先用栈把第一层入栈
- 循环把栈中节点逐个输出,如果存在子节点,子节点入下一层的栈
- 当当前栈中的节点都输出了, 把下一层的栈替换当前层的栈
- 依次输出当当前层的栈中没有任何节点的时候 输出完成
代码
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
}
看下官方题解
思路一直,整体的处理细节不太一样
递归 - 深度优先
动画演示
文字解析
- 通过层数index 来对 结果res 塞入遍历到的节点
- 每次遍历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