二叉树的中序遍历-94

题意

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

难度

简单

示例

示例 1:

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

输出:[1,3,2]

示例 2:

输入:root=[]

输出:[]

示例 3:

输入:root=[1]

输出:[1]

分析

对于这道题,我们需要先搞清楚,什么是二叉树的中序遍历。

前序遍历、中序遍历、后序遍历是二叉树的三种基本遍历方式,它们的主要区别在于访问根节点的时间。

  1. 前序遍历 (Preorder Traversal)
  2. 先访问根节点
  3. 接着访问左子树
  4. 最后访问右子树
  5. 遍历顺序:根 -> 左 -> 右
  6. 中序遍历 (Inorder Traversal)
  7. 先访问左子树
  8. 接着访问根节点
  9. 最后访问右子树
  10. 遍历顺序:左 -> 根 -> 右
  11. 后序遍历 (Postorder Traversal)
  12. 先访问左子树
  13. 接着访问右子树
  14. 最后访问根节点
  15. 遍历顺序:左 -> 右 -> 根

这里是一个简单的二叉树示意图:

A

/\

BC

/\/\

DEFG

对于这个二叉树:

  1. 前序遍历的结果是:A, B, D, E, C, F, G
  2. 中序遍历的结果是:D, B, E, A, F, C, G
  3. 后序遍历的结果是:D, E, B, F, G, C, A

我们可以写出一个中序遍历大概的算法雏形

public void traversal(TreeNode  node){

if(node.left!=null){

traversal(node.left);

}

read(node);

if(node.right!=null){

traversal(node.right);

}

}

同理我们稍微变换一下也可以得到对应的前序和后序遍历的算法

public void traversal(TreeNode  node){

read(node);

if(node.left!=null){

traversal(node.left);

}

if(node.right!=null){

traversal(node.right);

}

}



public void  traversal(TreeNode  node){

if(node.left!=null){

traversal(node.left);

}

if(node.right!=null){

traversal(node.right);

}

read(node);

}

最后我们只需要稍微对边界条件进行限制即可得到最终的算法。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
//创建一个列表,用于存放中序遍历的结果
List<Integer> res = new ArrayList<>();
//主方法,开始中序遍历
public List<Integer> inorderTraversal(TreeNode root){
//如果树不为空,则开始遍历
if(root!=null){
traversal(root);
}
//返回中序遍历的结果
return res;
}

//读取当前节点的值,并将其添加到结果列表中
public void read(TreeNode node){
res.add(node.val);
}

//中序遍历的核心逻辑
public void traversal(TreeNode node){
//如果当前节点的左子树不为空,先遍历左子树
if(node.left!=null){
traversal(node.left);
}
//访问当前节点
read(node);
//如果当前节点的右子树不为空,接着遍历右子树
if(node.right!=null){
traversal(node.right);
}
}
    
}

当输入为 1,null,2,3,二叉树可以表示为以下结构:

1

\

2

/

3

我们来模拟一下题解中的中序遍历过程。

  1. 初始调用:从根节点1开始调用inorderTraversal。
  2. 在inorderTraversal中,检查根节点1是否为null。既然不是,继续调用traversal。
  3. 在traversal中:
  4. 先检查节点1的左子树是否存在。但节点1的左子树是null,所以不做进一步递归。
  5. 然后,调用read方法访问节点1并将值1添加到结果列表res中。
  6. 接着,它会遍历节点1的右子树,即节点2。
  7. 为节点2重复步骤3:
  8. 先检查节点2的左子树。这里,节点2有一个左子节点3,所以它递归调用traversal为节点3。
  9. 对于节点3,它没有左子树,所以它直接访问该节点,并将值3添加到结果列表res中。
  10. 节点3没有右子树,所以没有进一步的递归调用。
  11. 回到节点2,在访问了它的左子树后,现在访问节点2本身,并将值2添加到结果列表res中。
  12. 节点2没有右子树,所以此处的遍历结束。
  13. 在完成以上所有步骤后,遍历完成。

根据以上描述,结果列表res为:[1, 3, 2]。

来看一下题解效率:

总结

递归处理是处理树形结构中最常用的一个操作,因为树的结构本质与递归殊途同归,在逻辑结构上二者十分近似,所以在学习树结构时,我们通常都可以类比递归,并从中获得启发。

力扣链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

一步一个脚印

不积跬步无以至千里,不积小流无以成江海。LeetCode - 100天从算法小白到卷王正式启动了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值