二叉树的遍历 → 不用递归,还能遍历吗

开心一刻

  某同学牙龈发炎去看医生,医生说要动手术

  同学说:以前没做过手术,有点紧张

  医生说:不用紧张,我也是第一次做手术

  听到医生这么说,同学更紧张了

  这时候护士走过来,问医生:麻药是打嘴里面还是打在嘴外面?

  医生说:打腿上吧,免得一会他跑了

前提准备

  关于什么是二叉树,不作过多介绍,不清楚的小伙先去充能下

  后续代码用 java 实现,但涉及到的数据结构、算法是通用的,希望大家不要被开发语言所禁锢

  二叉树节点定义类似如下

   value 存储数据, left 指向左子树, right 指向右子树

  二叉树结构类似如下

  二叉树的遍历分两种:深度遍历 和 广度遍历

  深度遍历又分三种:先序遍历、中序遍历、后续遍历,其中先序、中序、后续都是基于根(父)节点

    先序遍历:根(父)节点 -> 左子树 -> 右子树

    中序遍历:左子树 -> 根(父)节点 -> 右子树

    后续遍历:左子树 -> 右子树 -> 根(父)节点

  广度遍历也指层次遍历,从下至上或从下至上一层一层的从左至右遍历

  基于上图中的二叉树,我们来看看各种遍历的结果

  先序遍历:a b q w t u c d

  中序遍历:q b t w u a c d

  后续遍历:q t u w b d c a

  从上至下层次遍历:a b c q w d t u

  从下至上层次遍历:t u q w d b c a

深度遍历

  当我们对各种遍历有了概念上的了解之后,我们来看下具体实现

  先序遍历

  递归实现很简单,相信大家已经烂熟于心了

  如果不用递归,我们怎么实现先序遍历?

  我们知道,递归的时候,会保留现场信息(上下文),这是一个入栈的过程,只是由系统实现;当子递归完成之后,会出栈来到上层递归,这也是系统完成的

  如果我们将入栈、出栈的过程控制在我们自己的代码中,那么就不需要递归了,实现如下

  中续遍历

  递归实现

  非递归实现

  这个可能没那么好理解,结合具体的二叉树示例,脑中逐行模拟下代码执行,慢慢的就有感觉了

  后续遍历

  递归实现

  非递归实现

  用到了双栈,大家仔细揣摩下代码

  深度优先遍历

  指的就是先序遍历,前面已经实现过,这里就不再赘述

广度遍历

  一层一层的遍历二叉树,如果未明确指明,都是从左至右遍历

  广度遍历不满足递归的条件(至于是什么条件,自行去查),所以没法用递归处理

  从上至下层次遍历

  从根节点出发,从上至下,相当于先进先出,先进先出这样的关键字,我们第一时间想到的数据结构往往是:队列

  所以需要借助队列来实现从上至下的层次遍历,具体实现如下

  还是很简单的,也容易理解

  从下至上层次遍历

  前面已经实现了从上至下层次遍历,那是不是将其倒置一下就能实现从下至上层次遍历了?

  有这种感觉我们就去尝试,广度遍历需要用到队列,倒置需要用到,具体实现如下

  是不是觉得很有意思?

  广度优先遍历

    指的就是从上至下层次遍历,不再赘述

总结

  1、递归的实现往往比迭代实现要简单,也更好理解,但两者存在控件使用率的差异

    递归没有我们想象的那么简单,不同的问题有不同的决策过程

    而如何正确的找到决策过程,没有答案,全凭个人的感觉,可以通过多练题来提高这种感觉

  2、二叉树遍历是解决二叉树相关问题的基础,不同的遍历可以解决不同的问题

    二叉树相关的具体案例会单独开篇讲,届时大家结合这边文章,找一找二叉树问题的感觉

posted @ 2021-12-27 09:15  青石路  阅读(970)  评论(2编辑  收藏  举报