当前位置: 首页 > 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]]

相关文章:

  • 力扣-20.有效的括号
  • STM32标准库-ADC数模转换器
  • 基于ffmpeg+sdl的audio player
  • 模型重展UV后绘制纹理
  • [Java 基础]String 类
  • Java NIO详解:新手完全指南
  • 【技巧】dify前端源代码修改第一弹-增加tab页
  • python打卡day49@浙大疏锦行
  • 逻辑回归暴力训练预测金融欺诈
  • 电路图识图基础知识-远程/本地启停电动机(二十一)
  • 记录一篇HTTPS的文章
  • 如何让hustoj支持Java判题
  • 开放词汇检测分割YOLOE从pytorch到caffe
  • Spring状态机
  • Docker简述
  • React Hooks 的原理、常用函数及用途详解
  • Python打卡训练营学习记录Day49
  • 【Elasticsearch】Elasticsearch 在大数据生态圈的地位 实践经验
  • 2025年渗透测试面试题总结-小鹏[社招]车联网工程师(题目+回答)
  • 云南净餐馆备考单选题及答案
  • 具有价值的做pc端网站/杭州网站
  • 做英文网站2014/一周热点新闻
  • 建设网站企业运营/廊坊网站推广公司
  • 网站做签到功能/社区建站网站系统
  • 做网站用什么ps软件/长沙seo推广
  • 广东网站建设系统/seo优化技巧