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

C++算法训练营 Day13二叉树专题(1)

必备知识:
1.二叉树理论基础
2.二叉树的递归遍历

1. 二叉树的前序遍历

给你二叉树的根节点root,返回它节点值的前序遍历。

示例 1:

输入:root = [1,null,2,3]

输出:[1,2,3]

解释:
在这里插入图片描述
示例 2:

输入:root = [1,2,3,4,5,null,8,null,null,6,7,9]

输出:[1,2,4,5,6,7,3,8,9]

解释:
在这里插入图片描述
示例 3:

输入:root = []

输出:[]

示例 4:

输入:root = [1]

输出:[1]

  • 解题思路:

前序遍历的顺序是:根节点 -> 左子树 -> 右子树。这个递归算法通过深度优先搜索(DFS)实现前序遍历。

递归过程:

访问根节点:将当前节点值加入结果列表
遍历左子树:递归处理左子节点
遍历右子树:递归处理右子节点

完整代码如下:

class Solution {
public:void traversal(TreeNode* cur, vector<int>& res) {// 1.递归终止条件:当前节点为空if (cur == nullptr) return;// 2.访问根节点(前序遍历的核心操作)res.push_back(cur->val);  // 将当前节点值加入结果数组// 3.递归遍历左子树traversal(cur->left, res);// 4.递归遍历右子树traversal(cur->right, res);}//主函数:二叉树的前序遍历vector<int> preorderTraversal(TreeNode* root) {vector<int> result;      //创建结果数组traversal(root, result); //调用递归函数return result;           //返回遍历结果}
};

以下题为例:
在这里插入图片描述

  1. traversal(1):

    • 添加 1
    • 调用 traversal(2)
  2. traversal(2):

    • 添加 2
    • 调用 traversal(4)
  3. traversal(4):

    • 添加 4
    • traversal(4->left) 返回(空)
    • traversal(4->right) 返回(空)
  4. 回到 traversal(2):

    • 调用 traversal(5)
  5. traversal(5):

    • 添加 5
    • traversal(5->left) 返回
    • traversal(5->right) 返回
  6. 回到 traversal(2) 结束

  7. 回到 traversal(1):

    • 调用 traversal(3)
  8. traversal(3):

    • 添加 3
    • traversal(3->left) 返回
    • traversal(3->right) 返回
  9. 遍历完成

学会了前序遍历,那么中序遍历和后续遍历都是一个道理~

2.二叉树的中序遍历

给定一个二叉树的根节点root,返回它的中序遍历 。

示例 1:
在这里插入图片描述

输入:root = [1,null,2,3]
输出:[1,3,2]

示例 2:

输入:root = []
输出:[]

示例 3:

输入:root = [1]
输出:[1]

class Solution {
public:// 递归遍历函数void traversal(TreeNode* cur, vector<int>& res) {// 1. 递归终止条件:当前节点为空if (cur == nullptr) return;// 2. 递归遍历左子树traversal(cur->left, res);// 3. 递归遍历右子树traversal(cur->right, res);// 4. 访问根节点(后序遍历的核心操作)res.push_back(cur->val);  // 将当前节点值加入结果数组}// 主函数:二叉树的后序遍历vector<int> postorderTraversal(TreeNode* root) {vector<int> result;      // 创建结果数组traversal(root, result); // 调用递归函数return result;           // 返回遍历结果}
};

3.二叉树的后续遍历

给你一棵二叉树的根节点root,返回其节点值的 后序遍历 。

示例 1:

输入:root = [1,null,2,3]

输出:[3,2,1]

解释:在这里插入图片描述

示例 2:

输入:root = [1,2,3,4,5,null,8,null,null,6,7,9]

输出:[4,6,7,5,2,9,8,3,1]

解释:在这里插入图片描述

示例 3:

输入:root = []

输出:[]

示例 4:

输入:root = [1]

输出:[1]

class Solution {
public:// 递归遍历函数void traversal(TreeNode* cur, vector<int>& res) {// 1. 递归终止条件:当前节点为空if (cur == nullptr) return;// 2. 递归遍历左子树traversal(cur->left, res);// 3. 递归遍历右子树traversal(cur->right, res);// 4. 访问根节点(后序遍历的核心操作)res.push_back(cur->val);  // 将当前节点值加入结果数组}// 主函数:二叉树的后序遍历vector<int> postorderTraversal(TreeNode* root) {vector<int> result;      // 创建结果数组traversal(root, result); // 调用递归函数return result;           // 返回遍历结果}
};

4.二叉树的层序遍历

给你二叉树的根节点root,返回其节点值的 层序遍历。(即逐层地,从左到右访问所有节点)。

示例 1:
在这里插入图片描述

输入:root = [3,9,20,null,null,15,7]
输出:[[3],[9,20],[15,7]]

示例 2:

输入:root = [1]
输出:[[1]]

示例 3:

输入:root = []
输出:[]

  • 解题思路:

1.初始化队列:将根节点加入队列。

2.层级遍历:

  • 记录当前层节点数。
  • 依次处理当前层所有节点。
  • 将子节点加入队列。

3.存储层级结果:将当前层节点值存入结果。

4.重复:继续处理下一层。

class Solution {
public:vector<vector<int>> levelOrder(TreeNode* root) {queue<TreeNode*> que; //创建队列用于BFS//如果根节点非空,将其加入队列if (root != nullptr) que.push(root);//创建结果容器,每层一个子数组vector<vector<int>> result;//当队列非空时,继续处理while (!que.empty()) {//1. 获取当前层节点数量int size = que.size();//创建当前层的值容器vector<int> res;//2. 遍历当前层所有节点for (int i = 0; i < size; i++) {//获取队首节点并出队TreeNode* node = que.front();que.pop();//存储当前节点值vec.push_back(node->val);//3. 将子节点加入队列(下一层)if (node->left) que.push(node->left);if (node->right) que.push(node->right);}//4. 将当前层结果加入总结果result.push_back(res);}return result; // 返回按层组织的节点值}
};

以下题为例:
在这里插入图片描述

步骤队列状态当前层节点操作当前层结果总结果
1[3]1初始化队列,根节点3入队[]
1[3]1处理节点3:弹出3,值加入当前层[3]
1将3的左子9入队
1将3的左子20入队
1[9, 20]当前层完成,加入总结果
2[9, 20]2处理第一个节点9:弹出9,值加入当前层[9]
2[20]9无子节点
2[20]处理第二个节点20:弹出20,值加入当前层[9,20]
2将20的左子15入队
2将20的左子7入队
2[15,7]当前层完成,加入总结果[[3], [9,20]]
3[15,7]2处理第一个节点15:弹出15,值加入当前层[15][[3], [9,20]]
3[7]15无子节点
3[7]处理第二个节点7:弹出7,值加入当前层[15,7][[3], [9,20]]
3[]7无子节点
3当前层完成,加入总结果[[3], [9,20], [15,7]]
4[]0队列为空,遍历结束[[3], [9,20], [15,7]]
http://www.xdnf.cn/news/950833.html

相关文章:

  • Flutter状态管理框架RiverPod入门
  • 西电【网络与协议安全】课程期末复习的一些可用情报
  • 若依项目部署--传统架构--未完待续
  • 走进离线语音:安信可 VC‑01 智能模块全面拆解与 MCU 实战
  • Open3D 对点云进行去噪(下采样、欧式聚类分割)01
  • 【论文阅读】大模型优化器(Large Language Models As Optimizers)
  • 第一章-数据通信网络基础
  • 无需布线的革命:电力载波技术赋能楼宇自控系统-亚川科技
  • 删除远程已经不存在但本地仍然存在的Git分支
  • AWS EKS 集群日志上报观测云实践
  • 1.6 http模块nodejs 对比 go
  • 【字节拥抱开源】字节团队开源视频模型 ContentV: 有限算力下的视频生成模型高效训练
  • 安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(质检)
  • 浅谈 ST 表(Sparse Table,稀疏表)
  • 基于ffmpeg+sdl的audio player
  • uniapp 实现腾讯云IM群文件上传下载功能
  • 基于亚博K210开发板——WiFi 模块联网
  • C语言 学习 文件操作(开关,读写,定位,大小)操作 2025年6月8日12:19:24
  • C语言 学习 模块化编程 2025年6月9日19:39:17
  • 论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing
  • 触发DMA传输错误中断问题排查
  • Redis哨兵模式以及主从
  • LLM基础5_从零开始实现 GPT 模型
  • CMIP6气候模式资料概览
  • 免费在线PDF转图片工具
  • gephi绘制网络拓扑图:批量给节点着色
  • nginx安装和部署
  • 免费PDF转图片工具
  • NVIDIA CUDA 技术详解:开启 GPU 并行计算的大门
  • CocosCreator 之 JavaScript/TypeScript和Java的相互交互