Leetcode 94. 二叉树的中序遍历

【简单】力扣算法题解析LeetCode94:二叉树的中序遍历 本文介绍了二叉树中序遍历的迭代实现方法。通过使用栈模拟递归过程,算法首先将所有左子节点入栈,然后处理栈顶节点并转向右子树,确保按左-根-右顺序访问节点。Java代码中采用ArrayDeque作为栈结构,时间复杂度O(n),空间复杂度O(h)。该方法避免了递归的潜在栈溢出风险,适合处理深层树结构。文章包含示例说明、核心思路图解和完整可运行的Java代码实现,帮助读者直观理解迭代遍历过程。 阅读详情

题目

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

示例:

输入: [1,null,2,3]
在这里插入图片描述
输出: [1,3,2]

进阶:

  • 递归算法很简单,你可以通过迭代算法完成吗?

解答

解法一:递归

递归遍历没什么难度,这里不细说了。

复杂度:O(n) 时间,O(n) 空间。

代码
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    
    
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        inOrder(root, res);
        return res;
    }
    
    
    private void inOrder(TreeNode node, List<Integer> res) {
        if(node == null) return;
        
        inOrder(node.left, res);
        res.add(node.val);
        inOrder(node.right, res);
    }
}
结果

在这里插入图片描述

解法二:栈

步骤如下:

  1. 把当前结点的所有左结点压栈。
  2. 弹栈时遍历弹出的结点(注意此时弹出的结点的左子树必然已经遍历完毕)。
  3. 然后对弹出结点的右节点继续遍历。

复杂度:O(n) 时间,O(n) 空间。

代码
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        LinkedList<TreeNode> stack = new LinkedList<>();

        TreeNode cur = root;
        while(cur != null || !stack.isEmpty()) {
            while(cur != null) {
                stack.push(cur);
                cur = cur.left;
            }

            cur = stack.pop();
            res.add(cur.val);
            cur = cur.right;
        }
        
        return res;
    }
}
结果

在这里插入图片描述

解法三:线索二叉树(Morris算法)

要点如下:

  1. 如果当前结点有左子树,那么将左子树的最右结点 pre.right 指向当前结点作为线索。

  2. 同时将当前结点的 cur.left = null ,目的是再次遍历到当前结点时,说明当前结点的左子树已经遍历完毕了。

优点是省掉了 O(n) 空间的栈,缺点是会改变树的结构。

复杂度:O(n) 时间,O(n) 空间。

代码
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        TreeNode cur = root;
        TreeNode pre;
        while(cur != null) {
            if(cur.left == null) {
                res.add(cur.val);
                cur = cur.right;
            } else {
                pre = cur.left;
                while(pre.right != null) {
                    pre = pre.right;
                }
                
                pre.right = cur;
                TreeNode temp = cur;
                cur = cur.left;
                temp.left = null;                
            }
        }
        
        return res;
    }
}
优化代码:不改变树的结构

大体思想是:当再次遍历到 cur 时,判断 cur 左子树的最右结点 pre.right 是否等于 cur ,从而判断其左子树是否已经全部遍历。

显而易见,时间上并没有改变树结构的方法高效。

但优点是遍历并不会改变树的结构!!!

只是遍历而已,却把树结构改变了是什么鬼 :)

我觉得还是有必要优化一下。。。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        TreeNode cur = root;
        TreeNode pre;
        while(cur != null) {
            if(cur.left == null) {
                res.add(cur.val);
                cur = cur.right;
            } else {
                pre = cur.left;
                while(pre.right != null && pre.right != cur) {
                    pre = pre.right;
                }
                
                if(pre.right == null) {
                    pre.right = cur; 
                    cur = cur.left;
                }
                
                if(pre.right == cur) {
                    pre.right = null;
                    res.add(cur.val);
                    cur = cur.right;
                }
            }
        }
        
        return res;
    }
}
结果

在这里插入图片描述

Leetcode——94,二叉树中序遍历 /** * \* Created: liuhuichao * \* Date: 2019/7/16 * \* Time: 31:57 PM * \* Description:二叉树的中序遍历 : 中序遍历是先遍历左子树,然后访问根节点,然后遍历右子树 * \ * 给定一个二叉树,返回它的中序 遍历。 * <p> * 示例: * <p> * 输入... 阅读详情

相关推荐

从零到一:基于STM8的125KHz RFID读卡器实现与曼彻斯特码解析实战

本文详细介绍了基于STM8单片机的125KHz RFID读卡器实现过程,重点解析了曼彻斯特码的编码原理与解码算法。通过硬件电路设计、软件实现及性能优化,帮助开发者低成本构建稳定读取EM4100卡片的系统,适用于门禁、考勤等应用场景。

weixin_42525211的博客 234

LeetCode 力扣 94. 二叉树的中序遍历

题目描述(中等难度) 二叉树的中序遍历。 解法一 递归 学二叉树的时候,必学的算法。用递归写简洁明了,就不多说了。 public List<Integer> inorderTraversal(TreeNode root) { List<Integer> ans = new ArrayList<>(); getAns(root, ans); ...

wind_liang的博客 947

Apache Doris IP变更问题详解

Apache Doris IP变更问题详解

ith321的博客 7274

力扣94题:二叉树的中序遍历

方法时间复杂度空间复杂度特点递归OnO(n)OnOhO(h)Oh简单易实现,但依赖递归栈。迭代(栈)OnO(n)OnOhO(h)Oh显式使用栈,适合较大的二叉树。Morris 遍历OnO(n)OnO1O(1)O1无额外空间需求,但实现较复杂。不同方法适合不同场景,推荐优先使用递归和迭代方法,Morris 遍历适合对空间要求极高的情况。

weixin_48941116的博客 1097

3D医学影像分割实战:从数据预处理到模型训练全流程解析

本文详细解析了3D医学影像分割的全流程,从数据预处理到模型训练,重点介绍了nnUNet框架的应用技巧。通过实战案例,帮助开发者掌握如何处理复杂的.nii.gz文件格式、优化数据预处理流程以及高效训练3D分割模型,特别适合医学影像分析领域的从业者参考。

weixin_29098367的博客 222

绕开华为通道,获取解锁码解锁BootLoader

刷机有风险,操作需谨慎,如果因为各种因素导致手机变砖无法开机,本教程概不负责,望悉知 前言 这篇文章的大多内容是根据我自己找的一篇文章《绕开华为通道,获取解锁码解锁BootLoader》来编写的,里面的大部分内容是文章的原内容。下面的都是我参考文章中做了一些小部分的修改,增加了我华为P8手机的一些操作,下面开始讲述我的解锁过程。 因为华为官方在2018年的七八月份吧,关闭了解锁码的申请通道,这...

Martin.Mu `s Special Column 5万+

LeetCode第94题_二叉树的中序遍历

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

qq_40263592的博客 1307

美亚杯取证比赛必备:Veracrypt挂载+检材解压保姆级教程(附常见错误排查)

本文提供美亚杯数字取证竞赛的Veracrypt挂载与检材解压保姆级教程。详细解析从分卷压缩包解压(密码格式为MeiyaCup+年份)到使用Veracrypt正确挂载加密容器的全流程,并附有常见错误排查与高级应急方案,帮助选手高效突破技术门槛,顺利进入取证分析阶段。

alice7model的博客 1030

94.二叉树的中序遍历- 力扣(LeetCode)

如果为空了,也就是root是空节点了,说明当前子树的左节点都已经遍历完了,可以开始将左节点值加到res中了,从stack中弹出最近遍历到的节点,将节点值加到res中后让root = root.right。但中序遍历要先存左节点,所以是一直遍历左节点直到左节点为空,然后从栈中弹出上一个节点,这个节点将是当前子树的最左节点,将该节点的值存到res中,然后再令root = root.right。进入 inorder(3),递归调用 inorder(3.left)(即 inorder(None)),返回。

2401_87004385的博客 1545

debian mirrors 镜像源 riscv 64 赛昉 星光 starfive vf2 InRelease‘ doesn‘t support architecture ‘riscv64‘

debian mirrors 镜像 riscv 64 赛昉 星光2 starfive vf2 InRelease' doesn't support architecture 'riscv64'

qq_29758759的博客 1257

8、干式变压器

干式变压器的发展,是人类不断挑战材料科学和热物理极限的过程,每一次技术突破,都是在。温度升高,ε_r反而下降(因为分子活动性增强,极化响应变慢)。:固体导热的热阻比液体对流大一个数量级,这是无法逾越的物理规律。Nomex在高温下不是逐渐分解,而是保持性能直到一个临界点。如果 T_a = 40°C,则 T_c = 146.7°C。干式变压器(固体介质分隔):热场、电场、流场(空气)形成三维氢键网络,即使在高温下也能保持机械强度。:不是在现有技术上修修补补,而是寻找新的。仍在H级绝缘允许范围内(≤180°C)

renpeng2692873032的博客 228

leetcode力扣94. 二叉树的中序遍历

给定一个二叉树,返回它的中序遍历。 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [1,3,2] python写中序遍历其实和c++很像 # Definition for a binary tree node. # class TreeNode(object): # def __init__(self, x): #...

kaggle expert,全球排名前1000,清华计算机研究生,兴趣算法工程 557

【问题解决】解决 Python `PermissionError` 权限不足:文件/进程/端口全场景修复

本文总结了Python程序中常见的权限问题及解决方案,包括文件、进程和端口权限错误。文件权限问题通常由文件占用、权限不足或路径错误引起;进程问题多因权限不足或系统限制;端口问题则与端口占用、防火墙或特权端口相关。解决方案提供了详细的代码实现:文件权限管理器类(FilePermissionManager)包含检查权限(check_permission)、修复权限(fix_permission)、安全写入(safe_write)和安全删除(safe_delete)等方法,通过异常处理和临时文件等技术确保操作安全

博客 357

力扣(LeetCode)94. 二叉树的中序遍历

思路: 这次使用非递归法来遍历 中序遍历:根左右, ①所以在找到最左边的结点之前,我们一直找的是根左根左根左……直到我们找到最左边的子节点(假设其父节点是p) ②则这个时候应该一层一层的回找相关的右结点,这个时候就把当前结点转到p->right,继续进行①操作,直到找到最右边的结点 具体操作: (假设初始的时候根节点不为空,并申请一个栈Stack,这里用数组来代替,数组下标初始为-1) ①...

Pwnpanda的博客 447

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

LeetCode94-二叉树的中序遍历

LeetCode94-二叉树的中序遍历 最近全国疫情严重,待在家里没事干,马上又要准备春招了,最近刷刷题,记录一下!再说一句,武汉加油,大家出门记得戴口罩! 1、题目 给定一个二叉树,返回它的中序遍历。 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [1,3,2] 进阶: 递归算法很简单,你可以通过迭代算法完成吗? 2、思路 基于递归...

sk18192449347的博客 306

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

LeetCode-94. 二叉树的中序遍历

LeetCode-94. 二叉树的中序遍历 给定一个二叉树,返回它的中序 遍历。 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [1,3,2] 思路 分为递归版本和非递归版本。 递归 /** * Definition for a binary tree node. * public class TreeNode { * ...

Galip的博客 324

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

LeetCode 94二叉树的中序遍历

LeetCode 94二叉树的中序遍历 题目简述:给定一个二叉树,返回它的中序遍历。 输入:[1,null,2,3] 输出: [1,3,2] 思路:递归 class Solution { public: vector<int> res; void dfs(TreeNode *root) { if(!root) return; dfs(root->left); res.push_back(root->va

XBlog 237

《LeetCode力扣练习》第94题 二叉树的中序遍历 Java

《LeetCode力扣练习》第94题 二叉树的中序遍历 Java 一、资源 题目: 给定一个二叉树的根节点 root ,返回它的 中序 遍历。 示例 1: 输入:root = [1,null,2,3] 输出:[1,3,2] 示例 2: 输入:root = [] 输出:[] 示例 3: 输入:root = [1] 输出:[1] 示例 4: 输入:root = [1,2] 输出:[2,1] 示例 5: 输入:root = [1,null,2] 输出:[1,2] 提示: 树中节点数目在范围 [0,

XRT_knives的博客 317

【练习】【二叉树】力扣热题100 94. 二叉树的中序遍历

给定一个二叉树的根节点 root ,返回 它的 中序 遍历。输入:root = [1,null,2,3]输入:root = [1]输入:root = []输出:[1,3,2]

2402_86344613的博客 409

每日一题:Leetcode-94 二叉树的中序遍历

首先定义一个递归函数。

LIUCHANGSHUO的博客 467

LeetCode 94:二叉树的中序遍历

LeetCode 94:二叉树的中序遍历 题目描述解题思路代码实现总结 题目描述 给定一个二叉树,返回它的中序 遍历。 示例: 输入: [1,null,2,3] 1 2 / 3 输出: [1,3,2] 解题思路 二叉树的中序遍历:left -->root–>right (左跟右),借助栈结构,我们将每个按顺序遍历的节点,添加到arraylist当中。从二叉树的根节点开始,先将根节点...

香农三定律的博客 174

力扣 94.二叉树的中序遍历

给定一个二叉树的根节点。

2401_89122881的博客 369

golang力扣leetcode 94.二叉树的中序遍历

94.二叉树的中序遍历94.二叉树的中序遍历题解代码 94.二叉树的中序遍历 94.二叉树的中序遍历 题解 中序遍历:按照访问左子树——根节点——右子树的方式遍历这棵树 思路:递归和迭代 代码 package main type TreeNode struct { Val int Left *TreeNode Right *TreeNode } func inorderTraversal1(root *TreeNode) []int { if root == nil { return

清风 589

leetcode 94——二叉树的中序遍历

leetcode 94——二叉树的中序遍历 题目描述: 给定一个二叉树,返回它的中序 遍历。 示例: 输入: [1,null,2,3] 1 2 / 3 输出: [1,3,2] 进阶: 递归算法很简单,你可以通过迭代算法完成吗? 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/binary-tree-inorder-traversal 著作权...

weixin_44795839的博客 225

力扣(LeetCode) 94: 二叉树的中序遍历 - 解法思路

给定一个二叉树的根节点root,返回它的中序遍历。中序遍历是三种主要的树遍历方法之一。左子树 → 根节点 → 右子树遍历左子树(递归)访问根节点遍历右子树(递归)树: 123中序遍历: [1, 3, 2]- 从 1 开始,向左(无)→ 处理 1- 向右到 2,向左到 3 → 处理 3- 回到 2 → 处理 2对于二叉搜索树(BST),中序遍历产生有序的值(升序),因为所有左子节点 < 根节点 < 所有右子节点。递归和迭代方法都实现了 O(n) 时间复杂度。

Yao H. Wang's Blog 367

LeetCode 94. 二叉树的中序遍历

题目链接:LeetCode 94. 二叉树的中序遍历 给定一个二叉树,返回它的中序遍历。 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [1,3,2] 解题思路: 递归的方式,进行中序遍历 /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode...

error311的博客 139
上一篇: Leetcode 227. 基本计算器 II
下一篇: Leetcode 95. 不同的二叉搜索树 II
一纸浮萍
博客等级 码龄9年 11粉丝 103原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值