leetcode算法94.二叉树的中序遍历

简介: 当给定一个二叉树的根节点 root ,如何返回它的中序遍历?本文带大家解决这个问题。

一、leetcode算法



1、二叉树的中序遍历


1.1、题目


给定一个二叉树的根节点 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]


1.2、思路


思路一:此题我们可以使用Morris中序遍历来解决问题,首先有以下规则我们需要熟记于心


假设当前遍历到的节点为 x


1.如果x无左孩子,先将x的值加入答案数组,再访问x的右孩子,即x=x.right;


2.如果x有左孩子,则找到x左子树上最右的节点(即左子树一直向右找到最后一个为止),我们记为predecessor。根据predecessor的右孩子是否为空,进行下面的规则。


3.如果predecessor的右孩子为空,则将其右孩子指向x,然后访问x的左孩子,即x=x.left。


4.如果predecessor的右孩子不为空,则此时其右孩子指向x,说明我们已经遍历完x的左子树,我们将predecessor的右孩子置空,将x的值加入答案数组,然后访问x的右孩子,即x=x.right;


1.3、答案


21.png


class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<Integer>();
        TreeNode predecessor = null;
        while(root != null){
            //如果 x 有左孩子,则找到 x 左子树上最右的节点
            if(root.left != null){
                //predecessor节点就是当前root节点向左走一步,然后一直向右走到头
                predecessor = root.left;
                while(predecessor.right != null && predecessor.right != root){
                    predecessor = predecessor.right;
                }
                /**
                这里开始判断predecessor节点的情况如果predecessor 的右孩子为空,则将其右孩子指向 x,然后访问 x 的左孩子, 即 x =x.left      
                 */     
                if(predecessor.right == null){
                    predecessor.right = root;
                    root = root.left;
                }
                /**
                如果 predecessor 的右孩子不为空,则此时其右孩子指向 x,说明我们已经遍历完 x 的左子树,我们将predecessor 的右孩子置空,将 x 的值加入答案数组,然后访问 x 的右孩子,即 x =x.right。
                 */
                 else{
                     res.add(root.val);
                     predecessor.right = null;
                     root = root.right;
                 }
            }
            //如果 x 无左孩子,先将 x 的值加入答案数组,再访问 x 的右孩子,即 x =x.right。
            else{
                res.add(root.val);
                root = root.right;
            }
        }
        return res;
    }
}


复杂度分析


时间复杂度:O(n),其中 n 为二叉搜索树的节点个数。Morris 遍历中每个节点会被访问两次,因此总时间复杂度为 O(2n)=O(n)。


空间复杂度:O(1)。


相关文章
|
16天前
|
算法
分享一些提高二叉树遍历算法效率的代码示例
这只是简单的示例代码,实际应用中可能还需要根据具体需求进行更多的优化和处理。你可以根据自己的需求对代码进行修改和扩展。
|
20天前
|
存储 缓存 算法
如何提高二叉树遍历算法的效率?
选择合适的遍历算法,如按层次遍历树时使用广度优先搜索(BFS),中序遍历二叉搜索树以获得有序序列。优化数据结构,如使用线索二叉树减少空指针判断,自定义节点类增加辅助信息。利用递归与非递归的特点,避免栈溢出问题。多线程并行遍历提高速度,注意线程安全。缓存中间结果,避免重复计算。预先计算并存储信息,提高遍历效率。综合运用这些方法,提高二叉树遍历算法的效率。
45 5
|
20天前
|
存储 算法 Java
leetcode算法题-有效的括号(简单)
【11月更文挑战第5天】本文介绍了 LeetCode 上“有效的括号”这道题的解法。题目要求判断一个只包含括号字符的字符串是否有效。有效字符串需满足左括号必须用相同类型的右括号闭合,并且左括号必须以正确的顺序闭合。解题思路是使用栈数据结构,遍历字符串时将左括号压入栈中,遇到右括号时检查栈顶元素是否匹配。最后根据栈是否为空来判断字符串中的括号是否有效。示例代码包括 Python 和 Java 版本。
|
20天前
|
算法
树的遍历算法有哪些?
不同的遍历算法适用于不同的应用场景。深度优先搜索常用于搜索、路径查找等问题;广度优先搜索则在图的最短路径、层次相关的问题中较为常用;而二叉搜索树的遍历在数据排序、查找等方面有重要应用。
24 2
|
23天前
|
机器学习/深度学习 JSON 算法
二叉树遍历算法的应用场景有哪些?
【10月更文挑战第29天】二叉树遍历算法作为一种基础而重要的算法,在许多领域都有着不可或缺的应用,它为解决各种复杂的问题提供了有效的手段和思路。随着计算机科学的不断发展,二叉树遍历算法也在不断地被优化和扩展,以适应新的应用场景和需求。
25 0
|
2月前
|
算法
每日一道算法题(Leetcode 20)
每日一道算法题(Leetcode 20)
27 2
|
2月前
|
存储 算法
数据结构与算法学习十六:树的知识、二叉树、二叉树的遍历(前序、中序、后序、层次)、二叉树的查找(前序、中序、后序、层次)、二叉树的删除
这篇文章主要介绍了树和二叉树的基础知识,包括树的存储方式、二叉树的定义、遍历方法(前序、中序、后序、层次遍历),以及二叉树的查找和删除操作。
28 0
|
2月前
【LeetCode 43】236.二叉树的最近公共祖先
【LeetCode 43】236.二叉树的最近公共祖先
20 0
|
2月前
【LeetCode 38】617.合并二叉树
【LeetCode 38】617.合并二叉树
15 0
|
2月前
【LeetCode 37】106.从中序与后序遍历构造二叉树
【LeetCode 37】106.从中序与后序遍历构造二叉树
17 0