二叉树的层序遍历(JS版)

* 二叉树构造函数

复制代码
/**
 * 树节点
 * @class
 */
function TreeNode(val = 0, left = null, right = null) {
    this.val = val;
    this.left = left;
    this.right = right;
}
复制代码

 

直接上代码(含必要注释)

1. BFS(广度优先搜索)

复制代码
 1 /**
 2  * @param {TreeNode} root
 3  * @return {number[][]}
 4  */
 5 var levelOrder = function(root) {
 6     // 处理根节点为空的特殊情况
 7     if (root === null) return [];
 8     // 初始化一个队列(根节点入队)
 9     const q = [root];
10     // 初始化结果数组
11     const ans = [];
12     // 遍历节点队列
13     while (q.length > 0) {
14         // 记录当前队列中的节点数量
15         let cnt = q.length;
16         // 初始化当前层节点的容器
17         const level = [];
18         // 遍历当前层的节点
19         while (cnt-- > 0) {
20             const node = q.shift();
21             level.push(node.val);
22             // 左子节点先入队
23             if (node.left !== null) q.push(node.left);
24             // 右子节点后入队(以保持从左到右的顺序)
25             if (node.right !== null) q.push(node.right);
26         }
27         // 将当前层的遍历结果推入结果数组
28         ans.push(level);
29     }
30 
31     return ans;
32 };
复制代码

 

2. DFS(深度优先搜索)

2.1. 递归版本

复制代码
 1 var levelOrder = function(root) {
 2     // 容器(二维数组)
 3     const ans = [];
 4     // 搜索所有节点(从第一层开始,对应索引为0)
 5     dfs(root, 0, ans);
 6 
 7     return ans;
 8 };
 9 
10 var dfs = function(node, level, cont) {
11     // 如果节点为空,终止当前搜索
12     if (node === null) return;
13     // 比对当前结果容器中的层级结果容器数量与当前层(位置),
14     // 如果未初始化当前层的容器,则推入一个新数组
15     if (cont.length <= level) cont.push([]);
16     // 向当前层的结果容器中加入目标值
17     cont[level].push(node.val);
18     // 递归左子树
19     dfs(node.left, level + 1, cont);
20     // 递归右子树
21     dfs(node.right, level + 1, cont);
22 };
复制代码

2.2. 迭代版本

复制代码
 1 var levelOrder = function(root) {
 2     // 根节点为空直接返回
 3     if (root === null) return [];
 4     // 遍历结果
 5     const ans = [];
 6     // 节点栈(模拟系统栈,初始化时,root节点随即入栈)
 7     const stk = [root];
 8     // 层级栈(用于记录对应节点的所属层级,root所在层级记为0,也可以为1)
 9     const level_stk = [0];
10 
11     while (stk.length > 0) {
12         const node = stk.pop();
13         const level = level_stk.pop();
14         // 如果当前层级的数据容器在ans中还不存在(初始化一个新数组并推入)
15         if (ans.length <= level) ans.push([]);
16         // 在当前节点所属层级的数组中记录自身值
17         ans[level].push(node.val);
18         // 处理当前节点的右子树
19         if (node.right !== null) {
20             stk.push(node.right);
21             level_stk.push(level + 1);
22         }
23         // 处理当前节点的左子树
24         if (node.left !== null) {
25              stk.push(node.left);
26              level_stk.push(level + 1);
27         }
28     }
29 
30     return ans;
31 };
复制代码

 

End

posted @   樊顺  阅读(206)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?
点击右上角即可分享
微信分享提示