BFS:队列+树的宽搜

一、二叉树的层序遍历

. - 力扣(LeetCode)

该题的层序遍历和以往不同的是需要一层一层去遍历,每一次while循环都要知道在队列中节点的个数,然后用一个for循环将该层节点走完了再走下一层

cpp 复制代码
class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) 
    {
     vector<vector<int>> ret;
     queue<TreeNode*> q;
     if(root==nullptr) return ret;
     q.push(root);
     while(!q.empty())
     {
        int sz=q.size();//帮助我们控制一层一层出  因为上一层出完,下一层已经进去了
        vector<int> path;//统计结果
        for(int i=0;i<sz;++i)
        {
            TreeNode*t=q.front();
            q.pop();
            path.push_back(t->val);
            if(t->left) q.push(t->left);
            if(t->right) q.push(t->right);
        }
        ret.push_back(path);;
     }
     return ret;
    }
};

二、N叉树的层序遍历

. - 力扣(LeetCode)

cpp 复制代码
class Solution {
public:
    vector<vector<int>> levelOrder(Node* root) 
    {
        vector<vector<int>> ret;//记录最终的返回结果
        if(root==nullptr) return ret;
        queue<Node*> q;//层序遍历所需要的队列
        q.push(root);//先将根节点插入进去
        while(!q.empty()) //因为统计的是每层,所以我们没进去一次就要去统计一层。
        {
            int sz=q.size();
            //pop根节点的同时让他的孩子入队 
            //将左右孩子入队
            vector<int> path;//记录每层的结果
            for(int i=0;i<sz;++i)
            {
                 Node* t=q.front();
                 q.pop();
                 path.push_back(t->val);
                 //开始让后面的节点入队
                 for(Node* &child:t->children) 
                   if(child!=nullptr) 
                    q.push(child);
            }
            ret.push_back(path);
        }
        return ret;
    }
};

三、二叉树的锯齿形层序遍历

. - 力扣(LeetCode)

设置一个变量编辑层数,单层的不处理,双层的将path数组进行翻转

cpp 复制代码
class Solution {
public:
    vector<vector<int>> zigzagLevelOrder(TreeNode* root)
    {
       vector<vector<int>> ret;//帮助我们记录要返回的数组
       queue<TreeNode*> q;//层序遍历需要的队列
       if(root==nullptr) return ret;
       q.push(root);
       int k=1;//标记位
       while(!q.empty())
       {
          int sz=q.size();
          vector<int> path;//记录要插入的结果
          for(int i=0;i<sz;++i)
          {
          TreeNode*t=q.front();//删除前拿到队头节点
          q.pop();
          path.push_back(t->val);//将结果插入进去
          if(t->left) q.push(t->left);
          if(t->right) q.push(t->right); 
          }
          if(k%2==0) reverse(path.begin(),path.end());
          ++k;
          ret.push_back(path);
       }
       return ret;
    }
};

四、每个树行中找最大值

. - 力扣(LeetCode)

层序遍历的时候更新一下最大值即可!

cpp 复制代码
class Solution {
public:
    vector<int> largestValues(TreeNode* root) {
         vector<int> ret;
         if(root==nullptr) return ret;
         queue<TreeNode*> q;
         q.push(root);
         while(!q.empty())
         {
            size_t n=q.size();//统计当前层
            int temp=INT_MIN;
            for(size_t i=0;i<n;++i)
            {
                TreeNode*t=q.front();
                q.pop();
                temp=max(temp,t->val);//更新最大值
                //将孩子进队列
                if(t->left) q.push(t->left);
                if(t->right) q.push(t->right);
            }
            ret.emplace_back(temp);
         }
         return ret;
    }
};

五、二叉树的最大宽度(非常经典)

. - 力扣(LeetCode)

细节1:下标可能溢出

关键是这里借助**无符号整型**在溢出的时候自动根据32位,或者64位取模。

细节2:利用数组的存储方式给节点编号+移动赋值(右值引用提高效率)

用vector模拟queue 把孩子和其对应的下标存在数组中,每一层处理完再进行移动赋值。

cpp 复制代码
class Solution {
public:
    typedef pair<TreeNode*,unsigned int> PTU;
    int widthOfBinaryTree(TreeNode* root) {
      //用队列 直接连空节点也丢 超时
      //用数组模拟
      vector<PTU> q;//用数组来模拟队列
      q.emplace_back(root,1);
      unsigned int ret=1; //减掉之后不会影响结果
      while(!q.empty())
      {
        //先更新一下长度
        auto&[x1,y1]=q[0];
        auto&[x2,y2]=q.back();
        ret=max(ret,y2-y1+1);
        //用一个新的数组入队
         vector<PTU> temp;//用数组来模拟队列
         //让下一层进队列
         for(auto&[x,y]:q)
         {
            if(x->left) temp.emplace_back(x->left,y*2); //插入pair类型可以体现出emplace_back
            //和push_back的区别 push_back({x->left,y*2})
            if(x->right) temp.emplace_back(x->right,y*2+1);
         }
         //更新一个新的数组
         q=move(temp); //移动赋值  窃取资源 效率更高
      }
      return ret;
    }
};
相关推荐
√尖尖角↑10 分钟前
力扣——【1991. 找到数组的中间位置】
算法·蓝桥杯
Allen Wurlitzer11 分钟前
算法刷题记录——LeetCode篇(1.8) [第71~80题](持续更新)
算法·leetcode·职场和发展
百锦再2 小时前
五种常用的web加密算法
前端·算法·前端框架·web·加密·机密
刚入门的大一新生3 小时前
C++初阶-C++入门基础
开发语言·c++
碳基学AI3 小时前
北京大学DeepSeek内部研讨系列:AI在新媒体运营中的应用与挑战|122页PPT下载方法
大数据·人工智能·python·算法·ai·新媒体运营·产品运营
独家回忆3644 小时前
每日算法-250410
算法
袖清暮雨4 小时前
Python刷题笔记
笔记·python·算法
weixin_428498494 小时前
Visual Studio 中使用 Clang 作为 C/C++ 编译器时,设置优化选项方法
c语言·c++·visual studio
菜鸡中的奋斗鸡→挣扎鸡4 小时前
第十四届蓝桥杯大赛软件赛省赛C/C++ 大学 B 组
c语言·c++·蓝桥杯
风掣长空4 小时前
八大排序——c++版
数据结构·算法·排序算法