二叉树--纲领篇

104. 二叉树的最大深度

543. 二叉树的直径

144. 二叉树的前序遍历

 

在本文的最开始,首先介绍一下二叉树的解题思路。所有的二叉树解题思路,仅分为两种:

但无论使用哪种思路,都需要明确对于当前正在处理的二叉树节点,它需要「做什么」「什么时候做」。至于其他的节点,都可以通过「递归」的方法执行相同的操作

深入理解前中后序

我们可能存在一种固有思维,把「前中后」三种遍历理解为三种不同的顺序。其实这种理解仅仅是在第一层而已

前序遍历:刚刚进入一个节点的时候执行

中序遍历:当一个节点的左子树处理完,即将要处理右子树之前执行

后序遍历:即将离开一个节点的时候执行

说了这么多基础的,就是要帮你建立对二叉树正确的认识,然后你会发现:

二叉树的所有问题,就是让你在前中后序位置注入巧妙的代码逻辑,去达到自己的目的,你只需要单独思考每一个节点应该做什么,其他的不用你管,抛给二叉树遍历框架,递归会在所有节点上做相同的操作

小小实战

先来一个最最最简单的题目,前序遍历。详情可见题目 二叉树的前序遍历

首先我们用最常见的「遍历法」

image-20220226164025008 注:遍历法一般都是通过全局变量来记录结果

然后我们使用「分解子问题」的方法来解决一下这个问题

见识了两种不同思路,当我们在遇到题目的时候,思考:是否可以通过遍历一遍二叉树得到答案?如果不能的话,是否可以定义一个递归函数,通过子问题(子树)的答案推导出原问题的答案? 如果需要设计到子树信息, 建议使用后序遍历

上面给出的是一道基础题目的两种不同思路的方法,如果想见识更难的可见 二叉树所有路径

后序位置的特殊之处

说后序位置之前,先简单说下中序和前序

可以发现,前序位置的代码执行是「自顶向下」的,而后序位置的代码执行是「自底向上」的。这不奇怪,因为本文开头就说了前序位置是刚刚进入节点的时刻,后序位置是即将离开节点的时刻

但这里面大有玄妙,意味着前序位置的代码只能从函数参数中获取父节点传递来的数据;而后序位置的代码不仅可以获取参数数据,还可以获取到子树通过函数返回值传递回来的数据

例:现在有一棵二叉树,有两个简单的问题:

第一个问题可以这样写代码:

第二个问题可以这样写代码:

这两个问题的根本区别在于:一个节点在第几层,从根节点遍历过来的过程就能顺带记录;而以一个节点为根的整棵子树有多少个节点,需要遍历完子树之后才能数清楚

结合这两个简单的问题,可以品味一下后序位置的特点,只有后序位置才能通过返回值获取子树的信息

层序遍历

二叉树题型主要是用来培养递归思维的,而层序遍历属于迭代遍历,也比较简单,这里就过一下代码框架吧:

关于更多层序遍历的应用,可见 二叉树关于行的相关操作技巧