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

LeetCode hot 100—二叉树的中序遍历

题目

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

示例

示例 1:

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

示例 2:

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

示例 3:

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

分析

二叉树的中序遍历顺序是:先遍历左子树,然后访问根节点,最后遍历右子树。

递归法

递归是实现二叉树中序遍历最简单的方法,其基本思想是根据中序遍历的定义,递归地处理左子树、根节点和右子树。

时间复杂度:O(n), n 为二叉树节点的个数

空间复杂度:O(n),递归调用栈的空间,最坏情况下二叉树退化为链表,递归深度为 n

class Solution {
public:vector<int> inorderTraversal(TreeNode* root) {vector<int> result;inorder(root, result);return result;}
private:void inorder(TreeNode* node, vector<int>& result) {if (node == nullptr) {return;}// 递归遍历左子树inorder(node->left, result);// 访问根节点result.push_back(node->val);// 递归遍历右子树inorder(node->right, result);}
};

迭代法

迭代实现通常使用栈来模拟递归调用的过程。具体步骤如下:

  • 从根节点开始,将左子树的节点依次压入栈中,直到左子树为空
  • 弹出栈顶节点,访问该节点的值
  • 处理该节点的右子树,重复步骤 1 和 2

时间复杂度:O(n), n 为二叉树节点的个数

空间复杂度:O(n),递归调用栈的空间,最坏情况下二叉树退化为链表,递归深度为 n

class Solution {
public:vector<int> inorderTraversal(TreeNode* root) {vector<int> result;stack<TreeNode*> nodeStack;TreeNode* current = root;while (current != nullptr || !nodeStack.empty()) {// 将左子树的节点依次压入栈中while (current != nullptr) {nodeStack.push(current);current = current->left;}// 弹出栈顶节点并访问current = nodeStack.top();nodeStack.pop();result.push_back(current->val);// 处理右子树current = current->right;}return result;}
};

知识充电

二叉树性质

若规定根节点的层数为 1,则一棵非空二叉树的第 i 层上最多有 2^{i-1} 个节点

若规定根节点的层数为 1,则深度为 h 的二叉树的最大节点数是 2^{h}-1

对任何一棵二叉树,如果其叶节点个数为 n_{0},度为 2 的非叶节点个数为 n_{2},则有 n_{0}=n_{2}+1

常见操作

初始化

#include <iostream>
#include <vector>
#include <stack>// 二叉树节点定义
struct TreeNode {int val;TreeNode* left;TreeNode* right;TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};

插入节点

// 插入节点(以二叉搜索树为例)
TreeNode* insertNode(TreeNode* root, int val) {if (root == nullptr) {return new TreeNode(val);}if (val < root->val) {root->left = insertNode(root->left, val);} else {root->right = insertNode(root->right, val);}return root;
}
int main() {TreeNode* root = nullptr;root = insertNode(root, 50);insertNode(root, 30);insertNode(root, 20);insertNode(root, 40);insertNode(root, 70);insertNode(root, 60);insertNode(root, 80);return 0;
}

查找节点

// 查找节点(以二叉搜索树为例)
TreeNode* searchNode(TreeNode* root, int val) {if (root == nullptr || root->val == val) {return root;}if (val < root->val) {return searchNode(root->left, val);} else {return searchNode(root->right, val);}
}
// 辅助函数:插入节点
TreeNode* insertNode(TreeNode* root, int val) {if (root == nullptr) {return new TreeNode(val);}if (val < root->val) {root->left = insertNode(root->left, val);} else {root->right = insertNode(root->right, val);}return root;
}
int main() {TreeNode* root = nullptr;root = insertNode(root, 50);insertNode(root, 30);insertNode(root, 20);insertNode(root, 40);insertNode(root, 70);insertNode(root, 60);insertNode(root, 80);TreeNode* found = searchNode(root, 40);if (found) {std::cout << "Found node with value: " << found->val << std::endl;} else {std::cout << "Node not found." << std::endl;}return 0;
}

删除节点

// 找到右子树中的最小节点
TreeNode* findMin(TreeNode* node) {while (node->left != nullptr) {node = node->left;}return node;
}
// 删除节点(以二叉搜索树为例)
TreeNode* deleteNode(TreeNode* root, int val) {if (root == nullptr) {return root;}if (val < root->val) {root->left = deleteNode(root->left, val);} else if (val > root->val) {root->right = deleteNode(root->right, val);} else {// 情况 1: 没有子节点或只有一个子节点if (root->left == nullptr) {TreeNode* temp = root->right;delete root;return temp;} else if (root->right == nullptr) {TreeNode* temp = root->left;delete root;return temp;}// 情况 2: 有两个子节点TreeNode* temp = findMin(root->right);root->val = temp->val;root->right = deleteNode(root->right, temp->val);}return root;
}
// 辅助函数:插入节点
TreeNode* insertNode(TreeNode* root, int val) {if (root == nullptr) {return new TreeNode(val);}if (val < root->val) {root->left = insertNode(root->left, val);} else {root->right = insertNode(root->right, val);}return root;
}
int main() {TreeNode* root = nullptr;root = insertNode(root, 50);insertNode(root, 30);insertNode(root, 20);insertNode(root, 40);insertNode(root, 70);insertNode(root, 60);insertNode(root, 80);root = deleteNode(root, 30);return 0;
}

前序遍历

// 前序遍历(递归)
std::vector<int> preorderTraversalRecursive(TreeNode* root) {std::vector<int> result;if (root == nullptr) return result;result.push_back(root->val);auto leftResult = preorderTraversalRecursive(root->left);result.insert(result.end(), leftResult.begin(), leftResult.end());auto rightResult = preorderTraversalRecursive(root->right);result.insert(result.end(), rightResult.begin(), rightResult.end());return result;
}
int main() {TreeNode* root = new TreeNode(1);root->right = new TreeNode(2);root->right->left = new TreeNode(3);std::vector<int> preorderRecursive = preorderTraversalRecursive(root);return 0;
}

中序遍历

// 中序遍历(递归)
std::vector<int> inorderTraversalRecursive(TreeNode* root) {std::vector<int> result;if (root == nullptr) return result;auto leftResult = inorderTraversalRecursive(root->left);result.insert(result.end(), leftResult.begin(), leftResult.end());result.push_back(root->val);auto rightResult = inorderTraversalRecursive(root->right);result.insert(result.end(), rightResult.begin(), rightResult.end());return result;
}
int main() {TreeNode* root = new TreeNode(1);root->right = new TreeNode(2);root->right->left = new TreeNode(3);std::vector<int> inorderRecursive = inorderTraversalRecursive(root);return 0;
}

后序遍历

// 后序遍历(递归)
std::vector<int> postorderTraversalRecursive(TreeNode* root) {std::vector<int> result;if (root == nullptr) return result;auto leftResult = postorderTraversalRecursive(root->left);result.insert(result.end(), leftResult.begin(), leftResult.end());auto rightResult = postorderTraversalRecursive(root->right);result.insert(result.end(), rightResult.begin(), rightResult.end());result.push_back(root->val);return result;
}
int main() {TreeNode* root = new TreeNode(1);root->right = new TreeNode(2);root->right->left = new TreeNode(3);std::vector<int> postorderRecursive = postorderTraversalRecursive(root);return 0;
}

相关文章:

LeetCode hot 100—二叉树的中序遍历

题目 给定一个二叉树的根节点 root &#xff0c;返回 它的 中序 遍历 。 示例 示例 1&#xff1a; 输入&#xff1a;root [1,null,2,3] 输出&#xff1a;[1,3,2]示例 2&#xff1a; 输入&#xff1a;root [] 输出&#xff1a;[]示例 3&#xff1a; 输入&#xff1a;root […...

代码随想录算法训练营第35天 | 01背包问题二维、01背包问题一维、416. 分割等和子集

一、01背包问题二维 二维数组&#xff0c;一维为物品&#xff0c;二维为背包重量 import java.util.Scanner;public class Main{public static void main(String[] args){Scanner scanner new Scanner(System.in);int n scanner.nextInt();int bag scanner.nextInt();int[…...

与中国联通技术共建:通过obdiag分析OceanBase DDL中的报错场景

中国联通软件研究院&#xff08;简称联通软研院&#xff09;在全面评估与广泛调研后&#xff0c;在 2021年底决定采用OceanBase 作为基础&#xff0c;自研分布式数据库产品CUDB&#xff08;即China Unicom Database&#xff0c;中国联通数据库&#xff09;。目前&#xff0c;该…...

IDEA 接入 Deepseek

在本篇文章中&#xff0c;我们将详细介绍如何在 JetBrains IDEA 中使用 Continue 插件接入 DeepSeek&#xff0c;让你的 AI 编程助手更智能&#xff0c;提高开发效率。 一、前置准备 在开始之前&#xff0c;请确保你已经具备以下条件&#xff1a; 安装了 JetBrains IDEA&…...

斗地主小游戏

<!DOCTYPE html> <html><head><meta charset="utf-8"><title>斗地主</title><style>.game-container {width: 1000px;height: 700px;margin: 0 auto;position: relative;background: #35654d;border-radius: 10px;padding…...

如何改变怂怂懦弱的气质(2)

你是否曾经因为害怕失败而逃避选择&#xff1f;是否因为不敢拒绝别人而让自己陷入困境&#xff1f;是否因为过于友善而被人轻视&#xff1f;如果你也曾为这些问题困扰&#xff0c;那么今天的博客就是为你准备的。我们将从行动、拒绝、自我认知、实力提升等多个角度&#xff0c;…...

C# OnnxRuntime部署DAMO-YOLO人头检测

目录 说明 效果 模型信息 项目 代码 下载 参考 说明 效果 模型信息 Model Properties ------------------------- --------------------------------------------------------------- Inputs ------------------------- name&#xff1a;input tensor&#xff1a;Floa…...

基于GeoTools的GIS专题图自适应边界及高宽等比例生成实践

目录 前言 一、原来的生成方案问题 1、无法自动读取数据的Bounds 2、专题图高宽比例不协调 二、专题图生成优化 1、直接读取矢量数据的Bounds 2、专题图成果抗锯齿 3、专题成果高宽比例自动调节 三、总结 前言 在当今数字化浪潮中&#xff0c;地理信息系统&#xff08;…...

各种DCC软件使用Datasmith导入UE教程

3Dmax: 先安装插件 https://www.unrealengine.com/zh-CN/datasmith/plugins 左上角导出即可 虚幻中勾选3个插件,重启引擎 左上角选择文件导入即可 Blender导入Datasmith进UE 需要两个插件, 文章最下方链接进去下载安装即可 一样的,直接导出,然后UE导入即可 C4D 直接保存成…...

尚硅谷爬虫note15

一、当当网 1. 保存数据 数据交给pipelines保存 items中的类名&#xff1a; DemoNddwItem class DemoNddwItem(scrapy.Item): 变量名 类名&#xff08;&#xff09; book DemoNddwItem(src src, name name, price price)导入&#xff1a; from 项目名.items import 类…...

云原生系列之本地k8s环境搭建

前置条件 Windows 11 家庭中文版&#xff0c;版本号 23H2 云原生环境搭建 操作系统启用wsl(windows subsystem for linux) 开启wsl功能&#xff0c;如下图 安装并开启github加速器 FastGithub 2.1 下载地址&#xff1a;点击下载 2.2 解压安装文件fastgithub_win-x64.zip 2…...

关于tomcat使用中浏览器打开index.jsp后中文显示不正常是乱码,但英文正常的问题

如果是jsp文件就在首行加 “<% page language"java" contentType"text/html; charsetUTF-8" pageEncoding"UTF-8" %>” 如果是html文件 在head标签加入&#xff1a; <meta charset"UTF-8"> 以jsp为例子&#xff0c;我们…...

mysql foreign_key_checks

‌foreign_key_checks‌是一个用于设置是否在DML/DDL操作中检查外键约束的系统变量。该变量默认启用&#xff0c;通常在正常操作期间启用以强制执行参照完整性。 功能描述 foreign_key_checks用于控制是否在DML&#xff08;数据操纵语言&#xff09;和DDL&#xff08;数据定义…...

开发环境搭建-06.后端环境搭建-前后端联调-Nginx反向代理和负载均衡概念

一.前后端联调 我们首先来思考一个问题 前端的请求地址是&#xff1a;http://localhost/api/employee/login 后端的接口地址是&#xff1a;http://localhost:8080/admin/employee/login 明明请求地址和接口地址不同&#xff0c;那么前端是如何请求到后端接口所响应回来的数…...

REST API前端请求和后端接收

1、get请求&#xff0c;带"?" http://localhost:8080/api/aop/getResult?param123 GetMapping("getResult")public ResponseEntity<String> getResult(RequestParam("param") String param){return new ResponseEntity<>("12…...

道可云人工智能每日资讯|《奇遇三星堆》VR沉浸探索展(淮安站)开展

道可云元宇宙每日简报&#xff08;2025年3月5日&#xff09;讯&#xff0c;今日元宇宙新鲜事有&#xff1a; 《奇遇三星堆》VR沉浸探索展&#xff08;淮安站&#xff09;开展 近日&#xff0c;《奇遇三星堆》VR沉浸探索展&#xff08;淮安站&#xff09;开展。该展将三星堆文…...

服务器数据恢复—raid5阵列中硬盘掉线导致上层应用不可用的数据恢复案例

服务器数据恢复环境&故障&#xff1a; 某公司一台服务器&#xff0c;服务器上有一组由8块硬盘组建的raid5磁盘阵列。 磁盘阵列中2块硬盘的指示灯显示异常&#xff0c;其他硬盘指示灯显示正常。上层应用不可用。 服务器数据恢复过程&#xff1a; 1、将服务器中所有硬盘编号…...

【Pandas】pandas Series swaplevel

Pandas2.2 Series Computations descriptive stats 方法描述Series.argsort([axis, kind, order, stable])用于返回 Series 中元素排序后的索引位置的方法Series.argmin([axis, skipna])用于返回 Series 中最小值索引位置的方法Series.argmax([axis, skipna])用于返回 Series…...

esp32s3聊天机器人(二)

继续上文&#xff0c;硬件软件准备齐全&#xff0c;介绍一下主要用到的库 sherpa-onnx 开源的&#xff0c;语音转文本、文本转语音、说话人分类和 VAD&#xff0c;关键是支持C#开发 OllamaSharp 用于连接ollama&#xff0c;如其名C#开发 虽然离可玩还有一段距离&#xff0…...

pyside6学习专栏(九):在PySide6中使用PySide6.QtCharts绘制6种不同的图表的示例代码

PySide6的QtCharts类支持绘制各种型状的图表&#xff0c;如面积区域图、饼状图、折线图、直方图、线条曲线图、离散点图等&#xff0c;下面的代码是采用示例数据绘制这6种图表的示例代码,并可实现动画显示效果&#xff0c;实际使用时参照代码中示例数据的格式将实际数据替换即可…...

Java 语言特性(面试系列2)

一、SQL 基础 1. 复杂查询 &#xff08;1&#xff09;连接查询&#xff08;JOIN&#xff09; 内连接&#xff08;INNER JOIN&#xff09;&#xff1a;返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...

DAY 47

三、通道注意力 3.1 通道注意力的定义 # 新增&#xff1a;通道注意力模块&#xff08;SE模块&#xff09; class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...

在四层代理中还原真实客户端ngx_stream_realip_module

一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡&#xff08;如 HAProxy、AWS NLB、阿里 SLB&#xff09;发起上游连接时&#xff0c;将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后&#xff0c;ngx_stream_realip_module 从中提取原始信息…...

Python爬虫(二):爬虫完整流程

爬虫完整流程详解&#xff08;7大核心步骤实战技巧&#xff09; 一、爬虫完整工作流程 以下是爬虫开发的完整流程&#xff0c;我将结合具体技术点和实战经验展开说明&#xff1a; 1. 目标分析与前期准备 网站技术分析&#xff1a; 使用浏览器开发者工具&#xff08;F12&…...

Linux云原生安全:零信任架构与机密计算

Linux云原生安全&#xff1a;零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言&#xff1a;云原生安全的范式革命 随着云原生技术的普及&#xff0c;安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测&#xff0c;到2025年&#xff0c;零信任架构将成为超…...

大模型多显卡多服务器并行计算方法与实践指南

一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...

服务器--宝塔命令

一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行&#xff01; sudo su - 1. CentOS 系统&#xff1a; yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...

Xen Server服务器释放磁盘空间

disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...

【网络安全】开源系统getshell漏洞挖掘

审计过程&#xff1a; 在入口文件admin/index.php中&#xff1a; 用户可以通过m,c,a等参数控制加载的文件和方法&#xff0c;在app/system/entrance.php中存在重点代码&#xff1a; 当M_TYPE system并且M_MODULE include时&#xff0c;会设置常量PATH_OWN_FILE为PATH_APP.M_T…...

Proxmox Mail Gateway安装指南:从零开始配置高效邮件过滤系统

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐&#xff1a;「storms…...