《LeetCode 429 N叉树的层序遍历 队列宽搜BFS解法》

一.题目

429. N 叉树的层序遍历 - 力扣(LeetCode)

二.题目

2.1 思路讲解

层序遍历 的核心是利用队列按层处理。对于 N 叉树,操作与二叉树类似,只是每个节点的子节点数量不确定,需要依次将每个子节点入队。具体步骤如下:

  1. 初始化:创建一个队列,将根节点入队。若根节点为空,则直接返回空结果。

  2. 循环处理 :当队列不为空时,先记录当前队列的长度 size,这一数值代表当前层的节点个数。

  3. 处理当前层 :循环 size 次,每次从队列中取出一个节点,将其值加入当前层的列表中,并将该节点的所有子节点依次入队。

  4. 保存结果:当前层处理完毕后,将这一层的节点值列表加入最终结果集。

  5. 重复:继续下一层,直到队列为空。

这种方法能够保证节点按层从左到右的顺序被访问,且每一层的结果单独存放,最终返回完整的层序遍历结果。

三.代码演示

cpp 复制代码
/*
// Definition for a Node.
class Node {
public:
    int val;
    vector<Node*> children;

    Node() {}

    Node(int _val) {
        val = _val;
    }

    Node(int _val, vector<Node*> _children) {
        val = _val;
        children = _children;
    }
};
*/

class Solution {
public:
    vector<vector<int>> levelOrder(Node* root) 
    {
        vector<vector<int>> ret;//最终返回的结果
        queue<Node*>q;//队列
        //当节点为空
        if(root == nullptr) return ret;

        //不为空
        q.push(root);
        while(q.size())
        {
            int sz = q.size();//当层元素个数
            vector<int>tmp;//当层元素
            for(int i = 0;i < sz;i++)
            {
                Node* t = q.front();//获取队头
                q.pop();//删除队头
                tmp.push_back(t -> val);//添加队头元素

                //获取该节点的子节点
                for(const auto& ch : t->children)
                {
                    //不等于空
                    if(ch != nullptr)
                        q.push(ch);
                }
            }
            ret.push_back(tmp);
        }
        return ret;


            
    }
};

四.代码讲解

一、数据结构与初始化
  • ret:二维向量,存储最终层序遍历结果,每个子向量代表一层的节点值。

  • q:队列,用于按层顺序暂存待处理的节点。队列的先进先出特性保证了同层节点从左到右的顺序。

  • 边界处理 :如果根节点 root 为空,直接返回空结果集。

二、主循环:逐层处理

当队列不为空时,表示还有节点未处理,继续循环。

1. 记录当前层节点数

复制代码
int sz = q.size();

此时队列中存放的恰好是当前层的所有节点(上一层的子节点已全部入队),sz 即为本层节点个数。

2. 处理当前层节点

创建一个临时向量 tmp 用于存放本层的节点值。 循环 sz 次:

  • 取出队头节点 t,并将其值加入 tmp

  • t 的所有子节点(t->children)依次入队,只要子节点不为空。由于我们是在循环内逐次入队,但 sz 已经固定,因此不会干扰当前层的处理。

3. 存储本层结果

tmp 加入 ret,完成一层的遍历。

三、关键细节
  • 队列长度固定 :在进入内层循环前先记录 sz,确保只处理当前层的节点,避免将下一层节点提前混入。

  • 子节点入队 :使用范围 for 遍历 t->children,保证所有子节点按顺序加入队列,从而维持层序顺序。

五、流程图