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;
    }
};
相关推荐
UestcXiye20 分钟前
《TCP/IP网络编程》学习笔记 | Chapter 3:地址族与数据序列
c++·计算机网络·ip·tcp
好奇龙猫1 小时前
【学习AI-相关路程-mnist手写数字分类-win-硬件:windows-自我学习AI-实验步骤-全连接神经网络(BPnetwork)-操作流程(3) 】
人工智能·算法
霁月风2 小时前
设计模式——适配器模式
c++·适配器模式
sp_fyf_20242 小时前
计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-11-01
人工智能·深度学习·神经网络·算法·机器学习·语言模型·数据挖掘
香菜大丸2 小时前
链表的归并排序
数据结构·算法·链表
jrrz08282 小时前
LeetCode 热题100(七)【链表】(1)
数据结构·c++·算法·leetcode·链表
oliveira-time2 小时前
golang学习2
算法
咖啡里的茶i2 小时前
Vehicle友元Date多态Sedan和Truck
c++
海绵波波1072 小时前
Webserver(4.9)本地套接字的通信
c++
@小博的博客2 小时前
C++初阶学习第十弹——深入讲解vector的迭代器失效
数据结构·c++·学习