当前位置: 首页 > news >正文

基础算法精讲 13 | 二叉树的层序遍历

102. 二叉树的层序遍历

思路

  1. 如何层次遍历?

用队列.
TreeNode* tmpSwitch= q.front(); q.pop();记录一个就弹出一个,只是迭代更新用。

while (!q.empty()) {//把q中pop出去,用tmp接受需要有一个中间值帮忙。TreeNode* tmpSwitch= q.front();q.pop();tmpLevel.push_back(tmpSwitch->val);if (tmpSwitch->left != nullptr) q.push(tmpSwitch->left);if (tmpSwitch->right != nullptr) q.push(tmpSwitch->right);       }
  1. 如何实现分层效果?

vector tmp 和 for(int i = que.size(); i > 0; - -i)
计算一次队列中的个数,就计算过的结点 放入tmp容器中。

  for(int i = q.size(); i > 0; --i) {tmpSwitch = q.front();q.pop();tmpLevel.push_back(tmpSwitch->val);... ...}res.push_back(tmp);
  1. 3个记忆点。queue<TreeNode*>,vectortmpLevel,TreeNode* vector<vector> res。其中queue,tmp两个容器来回倒腾就好。
  2. 特例处理: 当根节点为空,则返回空列表 [ ] 。
 if(root==nullptr)return res;

完整代码

class Solution {
public:vector<vector<int>> levelOrder(TreeNode* root) {queue<TreeNode*> q;vector<vector<int>> res;if(root==nullptr)return res;//2.开始干活了q.push(root);while(!q.empty()){vector<int> tmpLevel;for(int i=q.size();i>0;i--){TreeNode* tmpSwitch = q.front();q.pop();tmpLevel.push_back(tmpSwitch->val);if(tmpSwitch->left!=nullptr) q.push(tmpSwitch->left);if(tmpSwitch->right!=nullptr)q.push(tmpSwitch->right);}res.push_back(tmpLevel);}return res;}
};

103. 二叉树的锯齿形层序遍历

思路

  1. 层序遍历
  2. 将分层输入的tmpLevel翻转一下啊
 if(count%2==1)reserver(tmpLevel);//把vector翻转void reserver(vector<int>& v){int l = 0;int r=v.size()-1;//【 )左闭右开while(l<r){int tmp=v[l];v[l]=v[r];v[r]=tmp;l++;r--;}}

完整代码

class Solution {
public://把vector翻转void reserver(vector<int>& v){int l = 0;int r=v.size()-1;//【 )左闭右开while(l<r){int tmp=v[l];v[l]=v[r];v[r]=tmp;l++;r--;}}vector<vector<int>> zigzagLevelOrder(TreeNode* root) {vector<vector<int>> res;queue<TreeNode*> q;int count=0;if(root==nullptr)   return res;q.push(root);while(!q.empty()){vector<int> tmpLevel;for(int i=q.size();i>0;i--){TreeNode* tmpSwith= q.front();q.pop();tmpLevel.push_back(tmpSwith->val);if(tmpSwith->left!=nullptr) q.push(tmpSwith->left);if(tmpSwith->right!=nullptr) q.push(tmpSwith->right);}if(count%2==1)reserver(tmpLevel);count++;res.push_back(tmpLevel);}return res;}
};

513. 找树左下角的值

思路

  1. 层序遍历
  2. vector<vector<int>> res换成 int res。并且加一个判断,如果是该层次遍历的第一个结点,就用res记录这个。这样每次一层的for遍历结束都会覆盖前一层的res。最后的res就是左下角的值。

经典的错误

class Solution {
public:int findBottomLeftValue(TreeNode* root) {queue<TreeNode*> q;int res=0;// if(root==nullptr)   //     return res;q.push(root);while(!q.empty()){for(int i=q.size();i>0;i--){TreeNode* tmp = q.front();q.pop();//经典的错误,q.size()是随q.pop()更新的if(i==q.size()) res=tmp->val;if(tmp->left) q.push(tmp->left);if(tmp->right) q.push(tmp->right);}            }return res;}
};

完整代码

class Solution {
public:int findBottomLeftValue(TreeNode* root) {queue<TreeNode*> q;int res=0;// if(root==nullptr)   //     return res;q.push(root);while(!q.empty()){int size= q.size();for(int i=size ; i>0 ; i--){TreeNode* tmp = q.front();q.pop();if(i==size) res=tmp->val;if(tmp->left) q.push(tmp->left);if(tmp->right) q.push(tmp->right);}            }return res;}
};

107. 二叉树的层序遍历 II

思路

  1. 层次遍历
  2. 再将vector<vector> res 翻转哈哈哈
  3. 有一个很致命的点就是 vector<int> level是辅助分层的,要定义在while中,不能定义在整个函数中。

完整代码

class Solution {
public:void reverse( vector<vector<int>>& v){int l = 0;int r = v.size()-1;while(l<r){vector<int> tmp = v[l];v[l] = v[r];v[r] = tmp;l++;r--;}}vector<vector<int>> levelOrderBottom(TreeNode* root) {vector<vector<int>> res;queue<TreeNode*> q;if(root==nullptr) return res;//开始层序遍历q.push(root);while(!q.empty()){   vector<int> level;        int size = q.size();for(int i=size;i>0;i--){TreeNode* tmp=q.front();q.pop();level.push_back(tmp->val);if(tmp->left!=nullptr) q.push(tmp->left);if(tmp->right!=nullptr) q.push(tmp->right);    }res.push_back(level);}reverse(res);return res;}
};

104. 二叉树的最大深度

111. 二叉树的最小深度

116. 填充每个节点的下一个右侧节点指针

思路

  1. 依旧应用了层数遍历。
  2. 在层序遍历的分层for中,将结点node串了起来。因为是队列,不能随机访问,所以就串一个pop一个
for(int i =0;i<size;i++){Node* cur = q.front();q.pop();if(i>0){pre->next = cur;}pre= cur;... ...}

完整代码

class Solution {
public:Node* connect(Node* root) {//Node* res;if(root==nullptr) return nullptr;queue<Node*> q;q.push(root);while(!q.empty()){Node* pre =nullptr;int size= q.size();for(int i =0;i<size;i++){Node* cur = q.front();q.pop();if(i>0){pre->next = cur;}pre= cur;if(cur->left) q.push(cur->left);if(cur->right) q.push(cur->right);}}    return root;   }
};

117. 填充每个节点的下一个右侧节点指针 II

思路

用bfs的话,就与上一题没有任何区别了

1302. 层数最深叶子节点的和

递归中的操作型

class Solution {
public:int maxLevel =-1;int depth = 0;int res = 0;void tra(TreeNode* t){if(t==nullptr)  return;depth++;if(depth> maxLevel){maxLevel=depth;res=t->val;}//这里不能写if(depth == maxLevel),经典的错误else if(depth == maxLevel){res+=t->val;}tra(t->left);tra(t->right);depth--;}int deepestLeavesSum(TreeNode* root) {tra(root);return res;}
};

BFS

已经碰到过很多次sumLevel的这种用法了。每一层我都计数,但是我一直会被覆盖。所以我记录的就是最后一层。

class Solution {
public:int deepestLeavesSum(TreeNode* root) {queue<TreeNode*> q;q.push(root);//定义sumLevelint sumLevel=0;while(!q.empty()){int size=q.size();//这里只是重新赋值,不是重新定义sumLevel = 0;for(int i =0;i<size;i++){TreeNode* tmp =q.front();q.pop();sumLevel+=tmp->val;if(tmp->left) q.push(tmp->left);if(tmp->right) q.push(tmp->right);}}return sumLevel;}
};
http://www.dtcms.com/a/618687.html

相关文章:

  • 网站设计包含哪些技术wordpress数据库更改账号密码
  • 如何通过reactor实现流式响应接口
  • vue-leaflet使用教程(一)
  • 江苏省徐州市建设银行网站技术培训网站
  • 如何取外贸网站域名建设网站平台费
  • python 贪心-dfs-dp
  • Android Studio - 使用 BuildConfig
  • 在ec2上部署Qwen2.5omini和Qwen3omini模型
  • 设备通信的艺术:从协议选型、性能调优到自定义实现的全维度技术实践
  • 过滤器模式、责任链模式
  • 做货源的网站郑州企业免费建站
  • HCIP笔记5--OSPF域间路由、虚链路、认证
  • Java 黑马程序员学习笔记(进阶篇27)
  • 海南网站推广建设温州市城市基础设施建设网站
  • CentOS 7 安装 unzip-6.0-21.el7.x86_64.rpm 步骤详解(附安装包)
  • 审计局网站建设管理创意设计广告
  • Goer-Docker系列-1-使用kubectl命令部署Web应用
  • php网站超市响应式网站建设方案
  • 家用路由器挑选指南:考量无线协议与Wi-Fi 7新技术参数
  • 站长工具网站提交沈阳网站优化怎么做
  • SAP FICO成本分解功能
  • 前端实现扫描大屏幕二维码上传图片并同步显示方案
  • 免费域名网站wordpress 修改子主题
  • 二叉树的前序遍历
  • 网站规划建设与管理维护课后答案四平市城乡建设局网站
  • 『大模型部署』NVIDIA Orin + bnb量化 + Qwen3-VL | 4bit、8bit量化
  • 网站建设状况vue快速搭建网站
  • 深入数据库性能优化:从参数调优到RAC高可用架构构建
  • MaxTex下载及LaTex环境配置
  • HttpServletResponse 详细指南