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

《代码随想录》刷题打卡day11:二叉树part01

文章目录

    • 1. 二叉树基础理论
    • 2. 题目打卡
      • DFS:
        • 144.二叉树的前序遍历
        • 145.二叉树的后序遍历
        • 94.二叉树的中序遍历
        • 递归法:
        • 迭代法:
        • 统一迭代法
      • BFS
        • 102.二叉树的层序遍历
        • 107.二叉树的层次遍历
        • 199.二叉树的右视图
        • 637.二叉树的层平均值
        • 429.N叉树的层序遍历
        • 515.在每个树行中找最大值
        • 116.填充每个节点的下一个右侧节点指针
        • 117.填充每个节点的下一个右侧节点指针II
        • 104.二叉树的最大深度
        • 111.二叉树的最小深度

1. 二叉树基础理论

二叉树种类:

满二叉树、完全二叉树(仅底层节点未填满,未填满的话节点必须在左边)

二叉搜索树(值:左>中>右)、平衡二叉搜索树(左右子树深度差不超过1)

二叉树存储方式

链式存储&顺序存储

链式存储图:

顺序存储图:

二叉树的遍历方式:

  • 深度优先遍历

    • 前序遍历(递归法,迭代法)
    • 中序遍历(递归法,迭代法)
    • 后序遍历(递归法,迭代法)

  • 广度优先遍历

    • 层次遍历(迭代法)

二叉树的定义

structTreeNode{intval;TreeNode*left;TreeNode*right;TreeNode(intx):val(x),left(nullptr),right(nullptr){}};

2. 题目打卡

DFS:

144.二叉树的前序遍历
145.二叉树的后序遍历
94.二叉树的中序遍历
递归法:

递归算法的三个要素。每次写递归,都按照这三要素来写,可以保证大家写出正确的递归算法!

  1. 确定递归函数的参数和返回值:确定哪些参数是递归的过程中需要处理的,那么就在递归函数里加上这个参数, 并且还要明确每次递归的返回值是什么进而确定递归函数的返回类型。

  2. 确定终止条件:写完了递归算法, 运行的时候,经常会遇到栈溢出的错误,就是没写终止条件或者终止条件写的不对,操作系统也是用一个栈的结构来保存每一层递归的信息,如果递归没有终止,操作系统的内存栈必然就会溢出。

  3. 确定单层递归的逻辑:确定每一层递归需要处理的信息。在这里也就会重复调用自己来实现递归的过程。

    classSolution{//前序遍历public:voidtraversal(TreeNode*cur,vector<int>&vec){if(cur==NULL)return;vec.push_back(cur->val);// 中traversal(cur->left,vec);// 左traversal(cur->right,vec);// 右}vector<int>preorderTraversal(TreeNode*root){vector<int>result;traversal(root,result);returnresult;}};
迭代法:
  1. 前序遍历:是中左右,每次先处理的是中间节点,那么先将根节点放入栈中,然后将右孩子加入栈,再加入左孩子。
    为什么要先加入 右孩子,再加入左孩子呢? 因为这样出栈的时候才是中左右的顺序。

    classSolution{public:vector<int>preorderTraversal(TreeNode*root){stack<TreeNode*>st;vector<int>result;if(root==NULL)returnresult;st.push(root);while(!st.empty()){TreeNode*node=st.top();// 中st.pop();result.push_back(node->val);if(node->right)st.push(node->right);// 右(空节点不入栈)if(node->left)st.push(node->left);// 左(空节点不入栈)}returnresult;}};
  2. 中序遍历:为了解释清楚,我说明一下 刚刚在迭代的过程中,其实我们有两个操作:
    处理:将元素放进result数组中
    访问:遍历节点
    分析一下为什么刚刚写的前序遍历的代码,不能和中序遍历通用呢,因为前序遍历的顺序是中左右,先访问的元素是中间节点,要处理的元素也是中间节点,所以刚刚才能写出相对简洁的代码,因为要访问的元素和要处理的元素顺序是一致的,都是中间节点。
    那么再看看中序遍历,中序遍历是左中右,先访问的是二叉树顶部的节点,然后一层一层向下访问,直到到达树左面的最底部,再开始处理节点(也就是在把节点的数值放进result数组中),这就造成了
    处理顺序和访问顺序是不一致的。

    那么在使用迭代法写中序遍历,就需要借用指针的遍历来帮助访问节点,栈则用来处理节点上的元素。

    classSolution{public:vector<int>inorderTraversal(TreeNode*root){vector<int>result;stack<TreeNode*>st;TreeNode*cur=root;while(cur!=NULL||!st.empty()){if(cur!=NULL){// 指针来访问节点,访问到最底层st.push(cur);// 将访问的节点放进栈cur=cur->left;// 左}else{cur=st.top();// 从栈里弹出的数据,就是要处理的数据(放进result数组里的数据)st.pop();result.push_back(cur->val);// 中cur=cur->right;// 右}}returnresult;}};
  3. 后序遍历:再来看后序遍历,先序遍历是中左右,后序遍历是左右中,那么我们只需要调整一下先序遍历的代码顺序,就变成中右左的遍历顺序,然后在反转result数组,输出的结果顺序就是左右中了。

统一迭代法

就是要处理的节点放入栈之后,紧接着放入一个空指针作为标记。这种方法可以叫做空指针标记法

classSolution{//中序遍历public:vector<int>inorderTraversal(TreeNode*root){vector<int>result;stack<TreeNode*>st;if(root!=NULL)st.push(root);while(!st.empty()){TreeNode*node=st.top();if(node!=NULL){st.pop();// 将该节点弹出,避免重复操作,下面再将右中左节点添加到栈中if(node->right)st.push(node->right);// 添加右节点(空节点不入栈)st.push(node);// 添加中节点st.push(NULL);// 中节点访问过,但是还没有处理,加入空节点做为标记。if(node->left)st.push(node->left);// 添加左节点(空节点不入栈)}else{// 只有遇到空节点的时候,才将下一个节点放进结果集st.pop();// 将空节点弹出node=st.top();// 重新取出栈中元素st.pop();result.push_back(node->val);// 加入到结果集}}returnresult;}};

BFS

classSolution{public:vector<vector<int>>levelOrder(TreeNode*root){queue<TreeNode*>que;if(root!=NULL)que.push(root);vector<vector<int>>result;while(!que.empty()){intsize=que.size();vector<int>vec;// 这里一定要使用固定大小size,不要使用que.size(),因为que.size是不断变化的for(inti=0;i<size;i++){TreeNode*node=que.front();que.pop();vec.push_back(node->val);if(node->left)que.push(node->left);if(node->right)que.push(node->right);}result.push_back(vec);}returnresult;}};
102.二叉树的层序遍历
107.二叉树的层次遍历
199.二叉树的右视图
637.二叉树的层平均值
429.N叉树的层序遍历
515.在每个树行中找最大值
116.填充每个节点的下一个右侧节点指针
117.填充每个节点的下一个右侧节点指针II
104.二叉树的最大深度
111.二叉树的最小深度
http://www.zskr.cn/news/1499412.html

相关文章:

  • 宁波10个高端楼盘石材装修实景案例合集(2026版) - 宁波融诚石业
  • 告别鼠标手!Kicad 6.0 原理图与PCB设计最全快捷键清单(附PDF速查表)
  • Apollo配置中心踩坑记:从IDE变量到Server.properties,优先级与缓存那些事儿
  • Spring AI实战:快速集成阿里通义千问
  • 助睿Max数据大屏实战(进阶篇):浏览器用户画像大屏的数据接入与交互全解析
  • 别再死记硬背了!用STM32CubeMX+FreeModbus库,5分钟搞定你的第一个Modbus从机
  • 2026年 除漆剂/除臭剂/絮凝剂/消泡剂厂家推荐榜:源头工艺与环保高效除味消泡实力品牌解析 - 品牌发掘
  • dubbo和oppenFeign是如何找到正确的url请求地址的
  • 2026 消费电子异形磁铁赛道 多家源头厂商技术能力多维对比 - 变量人生001
  • 2026 成都迪奥回收最新行情,经典款与新款二手流通价差解析 - 奢侈品回收评测
  • 2026选店指南,哈尔滨黄金回收门店参考手册 - 奢侈品回收测评
  • 摸底上海黄金回收渠道:2026年6月最新测评5家合规门店结果分享 - 奢侈品回收评测
  • S32K3安全机制实战:手把手教你用EIM模块注入ECC错误(附MCAL配置)
  • 新手选店攻略,对比哈尔滨各区黄金回收门店快速避坑 - 奢侈品回收测评
  • 无锡闲置包包出手指南,2026名牌包包回收没盒子还能高价出 - 奢侈品回收评测
  • 2026 合肥生成式引擎优化(GEO)行业权威测评报告 —— 基于第三方数据、产业底座与商业实效的中立评估 - 安徽工业
  • UVM验证进阶:深入start_item源码,解锁指定sequencer发送item的两种隐藏技巧
  • 2026揭阳防水补漏哪家靠谱?正规公司排名及避坑价格指南 - 苏易修缮
  • 2026 合肥生成式引擎优化(GEO)服务商权威测评报告 —— 基于第三方数据、产业底座与商业实效的中立评估 - 安徽工业
  • 2026年 哈尔滨短视频运营/代运营/企业获客/工厂推广,抖音全托管与制造业实战获客榜单推荐 - 品牌发掘
  • 手把手教你用STM32F103驱动TPC116S8 DAC模块(附完整工程代码)
  • 2026年风管来料加工全流程技术解析:降损提质实操指南 - 起跑123
  • 2026年稻花香大米源头厂家/五常稻花香/稻花香2号推荐榜:自产优质与正宗精选优质品牌深度解析 - 品牌发掘
  • Blender - Study Notes 9
  • 别再只装系统了!惠普光影精灵2升级固态硬盘后,这样设置才能让开机速度飞起来(Win10引导分区详解)
  • 唐山市中级经济师工商管理/人力资源管理:适配人群、岗位匹配与备考全攻略 - 众智商学院课程中心
  • 南宁黄金回收门店优选指南:认准正规品牌,轻松稳妥变现 - 奢侈品回收评测
  • 2026汕尾防水补漏哪家靠谱?正规公司排名及避坑价格指南 - 苏易修缮
  • 2026成都多门店横向测评香奈儿回收,五金掉色成色扣价标准实拍 - 奢侈品回收评测
  • 告别过拟合!用迁移学习和标签平滑提升你的高光谱Transformer模型精度