【数据结构与算法】LeetCode:二叉树

文章目录

  • 二叉树
    • 前序遍历
      • 二叉树的前序遍历
      • 二叉树展开为链表 (Hot 100)
    • 中序遍历
      • 二叉树的中序遍历 (Hot 100)
      • 验证二叉搜索树 (Hot 100)
      • 二叉搜索树中第K小的元素 (Hot 100)
    • 后序遍历
      • 二叉树的后序遍历
    • 层序遍历
      • 二叉树的层序遍历 (Hot 100)
      • 二叉树的最大深度
      • 翻转二叉树 (Hot 100)
      • 二叉树的右视图 (Hot 100)
      • 二叉树的锯齿形层序遍历

二叉树

前序遍历(Pre-order Traversal)、中序遍历(In-order Traversal)、后序遍历(Post-order Traversal)和层序遍历(Level-order Traversal)是四种常见的遍历树形结构的方法。四种遍历方法的主要区别在于它们访问节点的顺序不同。

  • 前序遍历 首先访问根节点,然后遍历左子树,最后遍历右子树。在遍历左、右子树时,仍然遵循前序遍历的规则。

  • 中序遍历 首先遍历左子树,然后访问根节点,最后遍历右子树。在遍历左、右子树时,仍然遵循中序遍历的规则。

  • 后序遍历 首先遍历左子树,然后遍历右子树,最后访问根节点。在遍历左、右子树时,仍然遵循后序遍历的规则。

前序、中序和后序遍历常用于对树形结构进行深度优先搜索(DFS)。通常使用递归或栈迭代来实现。

  • 层序遍历 从根节点开始,首先访问第一层节点,然后逐层向下访问。在同一层中,按照从左到右的顺序访问节点。

层序遍历常用于对树形结构进行广度优先搜索(BFS),通常使用队列迭代来实现。

前序遍历

二叉树的前序遍历

二叉树的前序遍历

递归:

class Solution {
public:void traversal(TreeNode* cur, vector<int>& vec) {if (cur == nullptr) 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);return result;}
};

迭代:

class Solution {
public:vector<int>preorderTraversal(TreeNode* root){stack<TreeNode*> st;vector<int> result;if(root == nullptr) return result;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);  // 左子树入栈}return result;}
};

二叉树展开为链表 (Hot 100)

二叉树展开为链表

class Solution {
public:void flatten(TreeNode* root) {vector<TreeNode*> node_list;// 前序遍历preorderTraversal(root, node_list); // 连接for(int i = 1; i < node_list.size(); i++){TreeNode* pre = node_list[i - 1], *cur = node_list[i];pre->left = nullptr;pre->right = cur;}}void preorderTraversal(TreeNode* root, vector<TreeNode*> & node_list){if(root == nullptr) return;node_list.push_back(root);preorderTraversal(root->left, node_list);preorderTraversal(root->right, node_list);}
};

中序遍历

二叉树的中序遍历 (Hot 100)

二叉树的中序遍历
递归

class Solution {
public:void traversal(TreeNode* cur, vector<int>& vec) {if (cur == NULL) return;traversal(cur->left, vec);  // 左vec.push_back(cur->val);    // 中traversal(cur->right, vec); // 右}vector<int> inorderTraversal(TreeNode* root) {vector<int> result;traversal(root, result);return result;}
};

迭代

class Solution {
public:vector<int> inorderTraversal(TreeNode* root){vector<int> result;stack<TreeNode*> st;TreeNode* cur = root;while(cur != nullptr || !st.empty()){if(cur != nullptr){st.push(cur);cur = cur->left;}else{cur = st.top();st.pop();result.push_back(cur->val);cur = cur->right;}}return result;}
};

验证二叉搜索树 (Hot 100)

验证二叉搜索树
二叉搜索树的中序遍历为递增序列

class Solution {
public:bool isValidBST(TreeNode* root) {stack<TreeNode*> stack;long long inorder = (long long)INT_MIN - 1;TreeNode* cur = root;while (!stack.empty() || cur != nullptr) {while (cur != nullptr) {stack.push(cur);cur = cur -> left;}cur = stack.top();stack.pop();// 如果中序遍历得到的节点的值小于等于前一个 inorder,说明不是二叉搜索树if (cur -> val <= inorder) {return false;}inorder = cur -> val;cur = cur -> right;}return true;}
};

二叉搜索树中第K小的元素 (Hot 100)

二叉搜索树中第K小的元素

class Solution {
public:int kthSmallest(TreeNode* root, int k) {stack<TreeNode *> stack;TreeNode* cur = root;while (cur != nullptr || stack.size() > 0) {while (cur != nullptr) {stack.push(cur);cur = cur->left;}cur = stack.top();stack.pop();--k;if (k == 0) {break;}cur = cur->right;}return cur->val;}
};

后序遍历

二叉树的后序遍历

二叉树的后序遍历
递归:

class Solution {
public:void traversal(TreeNode* cur, vector<int>& vec) {if (cur == nullptr) return;traversal(cur->left, vec);  // 左traversal(cur->right, vec); // 右vec.push_back(cur->val);    // 中}vector<int> postorderTraversal(TreeNode* root) {vector<int> result;traversal(root, result);return result;}
};

迭代:中右左遍历,然后reverse得到左右中

class Solution {
public:vector<int>postorderTraversal(TreeNode* root){stack<TreeNode*> st;vector<int> result;if(root==NULL) return result;st.push(root);while(!st.empty()){TreeNode* node = st.top();st.pop();result.push_back(node->val);if(node->left) st.push(node->left);if(node->right) st.push(node->right);}reverse(result.begin(), result.end());return result;}
};

层序遍历

二叉树的层序遍历 (Hot 100)

二叉树的层序遍历

class Solution {
public:vector<vector<int>> levelOrder(TreeNode* root) {queue<TreeNode*> que;if(root != nullptr) que.push(root);vector<vector<int>> result;while(!que.empty()){int size = que.size(); // 每一层的节点个数vector<int> vec;for(int i = 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);}return result;}
};

二叉树的最大深度

二叉树的最大深度

class Solution {
public:int maxDepth(TreeNode* root) {if (root == NULL) return 0;int depth = 0;queue<TreeNode*> que;que.push(root);while(!que.empty()) {int size = que.size();depth++; // 记录深度for (int i = 0; i < size; i++) {TreeNode* node = que.front();que.pop();if (node->left) que.push(node->left);if (node->right) que.push(node->right);}}return depth;}
};

翻转二叉树 (Hot 100)

翻转二叉树

class Solution {
public:TreeNode* invertTree(TreeNode* root) {queue<TreeNode*> que;if (root != NULL) que.push(root);while (!que.empty()) {int size = que.size();for (int i = 0; i < size; i++) {TreeNode* node = que.front();que.pop();swap(node->left, node->right); // 节点处理if (node->left) que.push(node->left);if (node->right) que.push(node->right);}}return root;}
};

二叉树的右视图 (Hot 100)

二叉树的右视图

class Solution {
public:vector<int> rightSideView(TreeNode* root) {queue<TreeNode*> que;if (root != NULL) que.push(root);vector<int> result;while (!que.empty()) {int size = que.size();for (int i = 0; i < size; i++) {TreeNode* node = que.front();que.pop();// 将每一层的最后元素放入result数组中if (i == (size - 1)) result.push_back(node->val); if (node->left) que.push(node->left);if (node->right) que.push(node->right);}}return result;}
};

二叉树的锯齿形层序遍历

二叉树的锯齿形层序遍历

class Solution {
public:vector<vector<int>> zigzagLevelOrder(TreeNode* root) {queue<TreeNode*> que;vector<vector<int>> res;if (root != NULL) que.push(root);while (!que.empty()) {vector<int> tmp;for(int i = que.size(); i > 0; i--) {TreeNode* node = que.front();que.pop();tmp.push_back(node->val);if (node->left != NULL) que.push(node->left);if (node->right != NULL) que.push(node->right);}if (res.size() % 2 == 1) reverse(tmp.begin(),tmp.end());res.push_back(tmp);}return res;}
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/54301.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

手机改IP地址怎么弄?全面解析与操作指南

在当今数字化时代&#xff0c;IP地址作为设备在网络中的唯一标识&#xff0c;其重要性不言而喻。有时候&#xff0c;出于隐私保护、网络访问需求或其他特定原因&#xff0c;我们可能需要更改手机的IP地址。然而&#xff0c;对于大多数普通用户来说&#xff0c;如何操作可能还是…

电梯,建模的常见话题

以下是最近一则"女婿开电梯门导致岳父惨死"的新闻&#xff0c;可惜生命的同时&#xff0c;也引发了一系列联想。 不少人不了解或者了解但经常下意识忽略&#xff1a;电梯的门和轿厢是分离的部件。部件之间的协作如果有失误&#xff0c;系统就会出问题。电梯可以看作是…

【Android 14源码分析】WMS-窗口显示-第二步:relayoutWindow -1

忽然有一天&#xff0c;我想要做一件事&#xff1a;去代码中去验证那些曾经被“灌输”的理论。                                                                                  – 服装…

Python-Learning

补充不熟悉的python知识 1 **是表示平方 注释是用来阐述代码要做什么&#xff0c;以及是如何做的 先编写行之有效的代码&#xff0c;再决定是对其做进一步改进&#xff0c;还是转而去编写新代码 列表常用是append&#xff0c;但也有pop&#xff0c;这个pop是输出一个值&…

kafka基本概念以及用法

kafka基本概念以及用法目录 文章目录 kafka基本概念以及用法目录一、什么是kafka&#xff1f;二、为什么要使用kafka?三、kafka的基本概念四、安装kafka(windows版本)五、命令行控制kafka生产消费数据&#xff0c;创建 删除topic六、java操作kafka消费生产 提示&#xff1a;以…

开源AI智能名片链动2+1模式S2B2C商城小程序源码与工业4.0的融合发展:机遇与挑战

摘要&#xff1a;本文探讨了工业4.0的三大主题&#xff0c;即智能工厂、智能生产和智能物流&#xff0c;分析在各主题下开源AI智能名片链动21模式S2B2C商城小程序源码与之融合的可能性、带来的机遇以及面临的挑战&#xff0c;旨在为相关产业的协同发展提供理论参考。 一、引言 …

Linux系统安装教程

Linux安装流程 一、前置准备工作二、开始安装Linux 一、前置准备工作 安装好VMWare虚拟机&#xff0c;并下载Linux系统的安装包&#xff1b; Linux安装包路径为&#xff1a;安装包链接 &#xff0c; 提取码为&#xff1a;4tiM 二、开始安装Linux

Java入门(基础,常见API,JVM,JUC并发编程)

一.javaSE Java初学者软件安装与idea快捷键-CSDN博客 Java基本概念&#xff08;新手入门&#xff09;_阿伟java资料-CSDN博客 二.常见API JavaAPI-CSDN博客 三.JVM JVM入门-CSDN博客 四.JUC并发编程 JUC并发编程-CSDN博客

Vue2如何在网页实现文字的逐个显现

目录 Blue留言&#xff1a; 效果图&#xff1a; 实现思路&#xff1a; 代码&#xff1a; 1、空字符串与需渲染的字符串的定义 2、vue的插值表达式 3、函数 4、mounted()函数调用 结语&#xff1a; Blue留言&#xff1a; 在国庆前夕&#xff0c;突发奇想&#xff0c;我想…

java项目实现钉钉异常告警实时监控

最近有个小伙伴问我&#xff0c;我们的项目核心业务的地方总是有异常&#xff0c;虽然有打印日志&#xff0c;但不能立马通知我&#xff1b;所以今天我就教大家如何实现异常报警实时提醒 1.需要有钉钉 自己新建的企业用户 2.建一个群&#xff0c;需要有三人以上&#xff1b;…

无环SLAM系统集成后端回环检测模块(loop):SC-A-LOAM以及FAST_LIO_SLAM

最近在研究SLAM目标检测相关知识&#xff0c;看到一篇论文&#xff0c;集成了SC-A-LOAM作为后端回环检测模块&#xff0c;在学习了论文相关内容后决定看一下代码知识&#xff0c;随后将其移植&#xff0c;学习过程中发现我找的论文已经集成了回环检测模块&#xff0c;但是我的另…

【智能算法应用】人工蜂鸟算法求解二维路径规划问题

摘要 本文采用人工蜂鸟算法&#xff08;Artificial Bee Colony Algorithm&#xff0c;ABC&#xff09;对二维路径规划问题进行求解。该算法模拟蜜蜂觅食行为&#xff0c;通过工蜂、观察蜂和侦查蜂的协作来找到最优路径。实验表明&#xff0c;ABC算法在处理路径规划问题上具有较…

项目管理系统如何实现项目申报流程自动化?

传统的项目申报流程往往繁琐复杂&#xff0c;涉及众多环节和部门间的协作&#xff0c;不仅耗时费力&#xff0c;还容易因人为疏忽而导致错误或延误。随着信息技术的飞速发展&#xff0c;项目管理系统的出现为项目申报流程的自动化提供了可能&#xff0c;极大地提升了申报效率和…

jQuery EasyUI 扩展

jQuery EasyUI 扩展 引言 jQuery EasyUI 是一个流行的 HTML5 框架,用于构建交互式网页界面。它提供了一系列的 UI 组件,如布局、窗口、数据网格等,使得网页开发变得更加简单快捷。然而,尽管 EasyUI 功能丰富,但在某些特定场景下,开发者可能需要更多的定制化功能或组件。…

【51单片机】点亮LED之经典流水灯

开发环境 开发板&#xff1a;普中51-单核-A2单片机&#xff1a;STC89C52RC&#xff08;双列直插40引脚 DIP40&#xff09;Keil uVision5 v9.61 最新版破解方法自行百度&#xff0c;相关文档和视频资料很多&#xff0c;我自己将这一操作记录下来当做博客发布&#xff0c;CSDN以…

通信工程学习:什么是ICMP因特网控制报文协议

ICMP&#xff1a;因特网控制报文协议 ICMP&#xff08;Internet Control Message Protocol&#xff0c;因特网控制报文协议&#xff09;是TCP/IP协议簇中的一个重要子协议&#xff0c;主要用于在IP主机和路由器之间传递控制消息。以下是关于ICMP协议的详细解释&#xff1a; 一…

用CSS创造三角形案例

6.3.2 用CSS创造三角形 用div来创建&#xff0c;角上是平分的&#xff0c;所以要是内部宽高为0&#xff0c;其他边透明&#xff0c;正好是三角形。 代码 div {border: 12px solid;width: 0;height: 0;border-color: transparent red transparent transparent; } 与伪元素aft…

HUAWEI WATCH GT 系列安装第三方应用

文章目录 适用机型概述官方文档从源码构建 hap 文件和对源码签名下载和安装DevEco Studio下载和安装首次启动推荐&#xff1a;设置IDE推荐的兼容版本环境&#xff08;可选&#xff09;安装并启用中文菜单插件 使用DevEco Studio打开项目并进行构建构建问题解决一、生成密钥和证…

Grafana链接iframe嵌入Web前端一直跳登录页面的问题记录

概述 公司有个项目使用到Grafana作为监控界面,因为项目方的环境极其复杂,仅物理隔离的环境就有三四个,而且每个都得部署项目,今天在某个环境测试,查看界面遇到一个比较奇怪的Grafana问题,后面针对该问题进行跟踪分析并解决,故而博文记录,用于备忘。 问题 登录项目We…

Hive数仓操作(十三)

一、JSON 数据 JSON&#xff08;JavaScript Object Notation&#xff09;是一种轻量级的数据交换格式&#xff0c;在不同的编程语言之间进行数据传输时非常通用和常用。JSON 格式简单直观&#xff0c;易于阅读和编写&#xff0c;并且可以被大多数编程语言轻松解析和生成。 1.…