前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >BFS:队列+树的宽搜

BFS:队列+树的宽搜

作者头像
小陈在拼命
发布2024-06-28 09:17:05
400
发布2024-06-28 09:17:05
举报
一、二叉树的层序遍历

. - 力扣(LeetCode)

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

代码语言:javascript
复制
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)

代码语言:javascript
复制
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数组进行翻转

代码语言:javascript
复制
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)

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

代码语言:javascript
复制
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 把孩子和其对应的下标存在数组中,每一层处理完再进行移动赋值。

代码语言:javascript
复制
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;
    }
};
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-06-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 二、N叉树的层序遍历
  • 三、二叉树的锯齿形层序遍历
  • 四、每个树行中找最大值
  • 五、二叉树的最大宽度(非常经典)
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档