LeetCode题号102__二叉树的层序遍历详细代码(C++版本)

声明::个人原创代码,转载需附上本文链接

题目::

题目分析::

本题要求实现二叉树的层序遍历,这是一种常见的树遍历方式,其特点是按照从上到下、从左到右的顺序逐层访问二叉树的所有节点。与普通的前序、中序、后序遍历不同,层序遍历需要将每一层的节点值存储在一个一维数组中,并将所有层的数组组合成一个二维数组作为输出。

层序遍历的关键在于如何有效地逐层访问节点。由于树的层级结构,我们不能简单地使用递归或迭代的方法来实现。相反,我们需要一种能够同时处理当前层和下一层节点的方法。队列(Queue)是一种非常适合这种需求的数据结构,因为它可以按照先进先出(FIFO)的原则存储和访问元素。

思路分析::

使用队列实现层序遍历

层序遍历的核心思想是使用队列来存储每一层的节点。通过逐层访问节点,可以保证按照从上到下、从左到右的顺序访问所有节点

双队列法

为了实现层序遍历,可以使用两个队列交替存储当前层和下一层的节点。这样可以避免在访问当前层时修改队列,从而简化代码逻辑。具体步骤如下:

  • 初始化两个空队列,one用于存储当前层的节点,two用于存储下一层的节点。

  • 将根节点加入one队列。

  • one队列不为空时,执行以下操作:

    • one队列中取出所有节点,访问它们的值,并将下一层的节点加入到two队列中。

    • one队列中的节点值存储在一个一维数组中,并将该数组添加到结果二维数组中。

    • 交换onetwo队列,以便下一次循环时处理下一层节点。

逐层访问 

从根节点开始,逐层访问节点,并将每一层的节点值存储在一个一维数组中。每访问完一层,将下一层的节点加入队列,直到所有层都被访问完毕。

代码分析

  • TreeNode结构体:定义了二叉树节点的结构体,包含节点值和左右子节点指针。

  • GetOneLevel函数:从当前层的队列中取出所有节点,访问它们的值,并将下一层的节点加入到下一层的队列中。返回当前层的节点值数组。这个函数通过一个while循环遍历当前层的所有节点,对于每个节点,取出其值并添加到结果数组中,然后检查是否有左右子节点,如果有则将它们加入到下一层的队列中。

  • levelOrder函数:使用两个队列交替存储当前层和下一层的节点,逐层访问二叉树的节点,并将每一层的节点值存储在一个一维数组中,最终返回一个二维数组。这个函数首先检查根节点是否为空,如果为空则直接返回空数组。然后初始化两个队列和一个结果数组。使用一个while循环来遍历所有层,每次循环中,通过调用GetOneLevel函数处理一层节点,并将结果添加到结果数组中。循环结束后,返回结果数组。

详细代码::

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
#include<queue>
class Solution {
public:
   //读取二叉树单层数据
   //AccessNodes存储当前正在访问的二叉树层所有节点
   //StorageNodes记录当前访问的二叉树层下一层所有节点
   vector<int> GetOneLevel(queue<TreeNode*>& AccessNodes,queue<TreeNode*>& StorageNodes){
        vector<int> OneLevel;
        TreeNode* temp;
        while(!AccessNodes.empty()){
            temp = AccessNodes.front();
            AccessNodes.pop();
            OneLevel.push_back(temp->val);
            //是否有左右子树
            if(temp->left!=nullptr) StorageNodes.push(temp->left);
            if(temp->right!=nullptr)    StorageNodes.push(temp->right);
        }
        //使用move语义加快返回速率
        return std::move(OneLevel);
   }
    vector<vector<int>> levelOrder(TreeNode* root) {
        queue<TreeNode*> one,two;
        vector<vector<int> > ans;
        if(root==nullptr)   return ans;
        //记录当前要访问的树层节点位于哪一个队列   
        int flag = 1; 
        one.push(root);
        while(1){
            if(flag == 1){
                //插入一层数据
                ans.push_back(GetOneLevel(one,two));
                flag = 0;
                if(two.empty()) break; //无下一层跳出循环
            }
            else{
                //插入一层数据
                ans.push_back(GetOneLevel(two,one));
                flag=1;
                if(one.empty()) break; //无下一层跳出循环
            }
        }
        return ans;
    }
};