Mr丶冷文

文章 分类 评论
125 10 8040

站点介绍

冷文学习者(KEVINLU98.COM),记录一个北漂小码农的日常业余生活
友链申请地址(直接评论即可): 传送门

二叉树中序遍历

MR丶冷文 2021-11-08 1471 0条评论 技术学习 二叉树数据结构

首页 / 正文
Freewind主题v1.5版本已发布,下载请移步Freewind 1.5,同时还有主题伴生插件Freewind Markdown,下载请移步 Freewind Markdown,有问题请在留言板,交换友链请直接在友链留言,我创建了一个主题交流群,有兴趣可以加下: 点此加入
报毒我说明一下,是因为我把主题的版权信息做了加密,其中用了eval,杀毒软件认为eval函数是一个危险的操作,这点介意的话请勿下载,我也没有强迫任何人去下载,也没有向大家收取一分钱的主题费用,所以也犯不着因为这些事情来喷我,喜欢就用,不喜欢就不用,就这么简单

发布于2022-10-28

引入

定义

首先我们先看看什么是二叉树的中序遍历?

二叉树的中序遍历即见名知意,对于每个节点,先遍历左叶子节点,再遍历当前节点,最后遍历右叶子节点

举例说明

如图所求:

https://imagebed-1252410096.cos.ap-nanjing.myqcloud.com/203201/7e0ba3c09c1045bd9793d0b821d92579.png

套用上述定义我们轻易到得这棵二叉树的中序遍历结果为:6、4、8、7、9、2、5、1、10、3

解释:

  • 我们先来到根节点1,按照定义,先遍历左叶子节点
  • 此时我们来到节点2,按照定义,先遍历左叶子节点
  • 我们再来到节点4,按照定义,先遍历左叶子节点
  • 我们再来到节点6,按照定义,先遍历左叶子节点,由于该节点的左叶子节点为空或者可以理解为没有左叶子节点,所以按照定义的第二步,遍历当前节点,该节点值为6,此时输出6,再按照定义的第3步,遍历右叶子节点,但右叶子节点为空或者可以理解为没有右叶子节点,所以该节点遍历完成
  • 而对于节点6的父节点4来说,此时等同于节点4的左叶子节点遍历完成,所以按照定义的第二步,遍历当前节点,该节点值为4,此时再输出4,再按照定义的第3步,遍历右叶子节点
  • 我们来到了节点4的右叶子节点7,对于节点7按照定义,先遍历左叶子节点
  • 我们来到节点8,按照定义,先遍历左叶子节点,由于该节点的左叶子节点为空或者可以理解为没有左叶子节点,所以按照定义的第二步,遍历当前节点,该节点值为8,此时输出8,再按照定义的第3步,遍历右叶子节点,但右叶子节点为空或者可以理解为没有右叶子节点,所以该节点遍历完成
  • 对于8的父节点7而言,此时等同于节点7的左叶子节点遍历完成,所以按照定义的第二步,遍历当前节点,该节点值为7,此时输出7,再按照定义的第3步,遍历右叶子节点
  • 我们来到节点9,按照定义,先遍历左叶子节点,由于该节点的左叶子节点为空或者可以理解为没有左叶子节点,所以按照定义的第二步,遍历当前节点,该节点值为9,此时输出9,再按照定义的第3步,遍历右叶子节点,但右叶子节点为空或者可以理解为没有右叶子节点,所以该节点遍历完成
  • 对于节点9的父节点7来说,右叶子节点遍历完成,按照定义,节点7遍历完成
  • 对于节点7的父节点4来说,右叶子节点遍历完成,按照定义,节点4遍历完成
  • 对于节点4的父节点2来说,此时等同于节点2的左叶子节点遍历完成,所以按照定义的第二步,遍历当前节点,该节点值为2,此时输出2,再按照定义的第3步,遍历右叶子节点
  • 我们来到节点5,按照定义,先遍历左叶子节点,由于该节点的左叶子节点为空或者可以理解为没有左叶子节点,所以按照定义的第二步,遍历当前节点,该节点值为5,此时输出5,再按照定义的第3步,遍历右叶子节点,但右叶子节点为空或者可以理解为没有右叶子节点,所以该节点遍历完成
  • 对于节点5的父节点2来说,右叶子节点遍历完成,按照定义,节点2遍历完成,
  • 对于节点2的父节点1来说,此时等同于节点1的左叶子节点遍历完成,所以按照定义的第二步,遍历当前节点,该节点值为1,此时输出1,再按照定义的第3步,遍历右叶子节点
  • 我们来到节点3,按照定义,先遍历左叶子节点
  • 我们来到节点10,按照定义,先遍历左叶子节点,由于该节点的左叶子节点为空或者可以理解为没有左叶子节点,所以按照定义的第二步,遍历当前节点,该节点值为10,此时输出10,再按照定义的第3步,遍历右叶子节点,但右叶子节点为空或者可以理解为没有右叶子节点,所以该节点遍历完成
  • 对于节点10的父节点3来说,此时等同于节点3的左叶子节点遍历完成,所以按照定义的第二步,遍历当前节点,该节点值为3,此时输出3,再按照定义的第3步,遍历右叶子节点,但右叶子节点为空或者可以理解为没有右叶子节点,所以该节点遍历完成
  • 对于节点3的父节点1来说,右叶子节点遍历完成,按照定义,节点1遍历完成
  • 到此,这棵二叉树遍历完成

递归遍历

思路

首先我们按照定义“对于每个节点,先遍历左叶子节点,再遍历当前节点,最后遍历右叶子节点”,我们不难发现,对每个节点都有相同的操作,此时就很容易想到递归算法了

Q:有了递归之后就应该去思考递归的终止条件是什么?

A:对于每个节点都有相同的操作,那如果当前节点为空呢?比如上图中的节点6的左叶子节点,遍历到该节点了,它自己都为空或是说这个节点都不存在,也就没有必要继续遍历其叶子节点了,所以我们递归的终止条件就为当前节点不为空

Q:如何递归调用呢?

A:我们按照定义,当进入递归后先要遍历左叶子节点,而遍历左叶子节点与遍历当前节点的逻辑一样,所以直接对左叶子节点递归调用当前方法;遍历完左叶子节点,我们就要遍历(假设我们的遍历操作就是打印出来)当前节点了,我们直接打印当前节点值,接下来要遍历右叶子节点,而遍历右叶子节点与遍历当前节点的逻辑一样,所以直接对右叶子节点递归调用当前方法

代码实现

/**
 * 我们就按照力扣上的二叉树的定义来定义二叉树
 * 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;
 *     }
 * }
 */
public void inorder(TreeNode root) {
  //当前节点为空或是说当前节点都不存在,也就没有必要继续遍历其叶子节点了
  if (root == null) return;
    //遍历左叶子节点
  inorder(root.left);
  //遍历当前节点
  System.out.print(root.val + "\t");
  //遍历右叶子节点
  inorder(root.right);
}

非递归遍历

思路

首先我们先来到节点1,中序遍历的话就是要先遍历左叶子节点,我们来到节点2,同理到节点4、节点6,我们发现对于左叶子节点我们访问的顺序是1、2、4、6,而最后的输出顺序为6、4、2、1,细心的朋友是不是已经发现什么了?先进后出,我们很容易就能想到栈

现在我们初步先使用栈做为容器对根节点的左叶子节点进行压栈操作,直到左叶子节点为空,我们压栈数据依次为1、2、4、6,那么我们弹栈操作就等于是遍历,节点6先出栈,接着节点4出栈,此时我们不能直接继续出栈,因为我们是中序遍历,我们遍历完当前节点后需要遍历其右叶子节点

对于节点4的右叶子节点7而言,我们可以将其看作是一棵二叉树,所以从节点7开始对左叶子节点进行压栈操作,直到左叶子节点为空,此时我们压栈数据为7、8,此时栈内数据按压栈顺序依次为1、2、7、8,再次进行弹栈操作,节点8先出栈,节点7出栈,此时又不能直接继续出栈,因为节点7有右叶子节点

重复上述操作直到遍历完所有节点

我们可以很容易发现不用递归的话我信可以用栈来帮助我们完成这项操作,从根节点开始遍历其左叶子节点,直到左叶子节点为空,出栈,若有右叶子节点则继续重复压栈操作,反之继续出栈,直到栈为空完成遍历

代码实现

public static void inorderTraversal(TreeNode root) {
  if (root == null) return;
  TreeNode node = root;
  Stack<TreeNode> stack = new Stack<>();
  while (!stack.isEmpty() || node != null) {
    while (node != null) {
      stack.push(node);
      node = node.left;
    }
    node = stack.pop();
    System.out.print(node.val + ", ");
    if (node.right != null)
      node = node.right;
    else
      node = null;
  }
}

执行结果

我们运行一下代码,得到如下结果

https://imagebed-1252410096.cos.ap-nanjing.myqcloud.com/203208/a84c8099a162408892e05376d26b6a6a.png

评论(0)

热门文章

最新评论

  • boy

    学习一下

  • ThatDay

    谢谢

  • ThatDay

    好东西

  • ThatDay

    感谢

  • ThatDay

    感谢

日历

2024年04月

 123456
78910111213
14151617181920
21222324252627
282930    

文章目录

站点公告
Freewind主题v1.5版本已发布,下载请移步Freewind 1.5,同时还有主题伴生插件Freewind Markdown,下载请移步 Freewind Markdown,有问题请在留言板,交换友链请直接在友链留言,我创建了一个主题交流群,有兴趣可以加下: 点此加入
报毒我说明一下,是因为我把主题的版权信息做了加密,其中用了eval,杀毒软件认为eval函数是一个危险的操作,这点介意的话请勿下载,我也没有强迫任何人去下载,也没有向大家收取一分钱的主题费用,所以也犯不着因为这些事情来喷我,喜欢就用,不喜欢就不用,就这么简单
点击小铃铛关闭