【算法与数据结构】:二叉树的遍历运算

192 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第24天,点击查看活动详情

1、写在前面

大家好,我是翼同学。今天文章的内容是:

  • 二叉树的遍历运算

2、内容

遍历二叉树,就是指按照一定的规则和顺序,逐一访问二叉树的所有结点,每个结点有且只有一次被访问到。由于二叉树是非线性结构,因此,对于二叉树的遍历事实上就是将二叉树的各个结点排列成一个线性序列。

备注:遍历的含义包括读取、输出、修改结点的信息等。

现给定一颗二叉树如下图:

image.png

那么经过遍历运算后,结果为:

  • 前序遍历:[ABDHIECFGA、B、D、H、I、E、C、F、G]
  • 中序遍历:[HDIBEAFCGH、D、I、B、E、A、F、C、G]
  • 后序遍历:[HIDEBFGCAH、I、D、E、B、F、G、C、A]

现给出二叉链表的简单类定义如下:

image.png

递归遍历

由于二叉树是递归定义的,因此我们可以采用递归的方法来实现二叉树的前序、中序、后序遍历操作。这不仅容易理解,在代码层面上来看也很简洁干净。在递归遍历中,对二叉树的遍历其实是在对各子树分别遍历的基础上进行的。

下面给出三种递归遍历二叉树的参考代码。

前序遍历

前序遍历二叉树的算法如下:

  1. 如果二叉树为空,则直接return;,结束本层递归
  2. 如果二叉树不为空,那么先访问根结点,接着前序遍历左子树,最后前序遍历右子树。

代码如下:

image.png

中序遍历

中序遍历二叉树的算法如下:

  1. 如果二叉树为空,则直接return;,结束本层递归
  2. 如果二叉树不为空,那么先中序遍历左子树,接着访问根结点,最后中序遍历右子树。

代码如下:

image.png

后序遍历

后序遍历二叉树的算法如下:

  1. 如果二叉树为空,则直接return;,结束本层递归
  2. 如果二叉树不为空,那么先后序遍历左子树,接着后序遍历右子树,最后访问根结点。

代码如下:

image.png


迭代遍历

在递归实现中,每次递归调用都会将函数的局部变量,参数值以及返回地址都压入调用栈中,最后递归返回时只需在栈中弹出上一次递归的各项信息。因此我们可以使用栈来实现对二叉树的遍历运算,仿照递归算法的执行过程中 递归工作栈的工作原理,写出对应的非递归算法,也就是迭代遍历。

下面给出三种迭代遍历二叉树的参考代码。

前序遍历

对于二叉树的非递归前序遍历,算法思想为:每遇到一个结点时,就访问该结点,然后将该结点压入到栈中,接着遍历它的左子树,遍历完左子树后,栈顶弹出该结点。最后去遍历该结点的右子树,依此类推。

代码如下:

image.png

中序遍历

对于二叉树的非递归中序遍历,算法思想为:每遇到一个结点时,就将该结点压入到栈中,然后去遍历它的左子树,遍历完左子树后,从栈顶弹出该结点并访问。最后再去遍历该结点的右子树,依此类推。

代码如下:

image.png

后序遍历

对于二叉树的非递归后序遍历,算法思想为:每遇到一个结点时,就将该结点压入到栈中,然后去遍历它的左子树,遍历完左子树后再去遍历该结点的右子树,当右子树遍历完成后,才能从栈顶弹出该结点并访问,依此类推。

需要注意的是,下面代码利用到了特征位LEFTRIGHT来表示当前结点是从左子树返回还是从右子树返回。也就是说,如果是从左子树返回来的结点就必须继续遍历右子树,遍历完右子树后才能访问结点。

代码如下:

image.png

3、写在最后

好了,文章的内容就到这里,感谢观看。