vlambda博客
学习文章列表

风哥带你手撕算法之吃透二叉树(2)

程序员吴乘风。


本篇 LeetCode 题目列表:

114. 二叉树展开为链表

144. 二叉树的前序遍历

94. 二叉树的中序遍历

145. 二叉树的后序遍历

上一篇文章,风哥简要介绍了 模板思维递归思想 以及手撕第一道二叉树算法题。

今天我将带大家继续攻破二叉树经典题,并且附上详细解题思路。


一、算法实战


第一题:114. 二叉树展开为链表

关键词二叉树 递归 原地  

风哥带你手撕算法之吃透二叉树(2)


这题的主要目标,就是将二叉树变成一个按 先序遍历 顺序存储节点的 链表 ,并且要 原地

原地,简单来说就是不依赖或依赖少数的额外资源,仅依靠输出来覆盖输入的一种算法操作。

在这题中的体现,就是不要通过外部容器(额外数组、链表等)进行转存,仅通过将二叉树左节点转移到右节点的操作,将二叉树变成一个 root.left = null 的链表。


思路

我们可以依次遍历 6 5 4 3 2 1 ,这个顺序就是 先序遍历的逆序 ,即“右 -> 左 -> 中”。

而后序遍历与这种模式最接近,即"左 -> 右 -> 中":先进入当前节点的左子树,再进入当前节点的右子树,最后再对当前节点进行操作,模板即我们在上一篇提到的:

风哥带你手撕算法之吃透二叉树(2)

所以我们对其改造,变成这一题我们所需要的遍历顺序:逆先序遍历“右 -> 左 -> 中”:先进入当前节点的右子树,再进入当前节点的左子树,最后再对当前节点进行操作,模板如下:

风哥带你手撕算法之吃透二叉树(2)

知道了遍历顺序,接下来我们要做的,就是按照顺序,将 6 接到上一级节点 5 的右子树位置, 5 接到上一级节点 4 的位置...以此类推。

这样,就可以依题意得到先序遍历链表了,是不是很简单?

风哥带你手撕算法之吃透二叉树(2)

这里的话,利用一个全局变量 pre,更新当前根节点的右指针为 pre,左指针为 null。

源码

风哥带你手撕算法之吃透二叉树(2)

左子树一定要记得置空、删除。

心得

熟记二叉树遍历模板,在遇到具体问题时需灵活变通,适当使用各种遍历的逆序以及变种。



接下来,对于之前反反复复提到的先序遍历、中序遍历、后序遍历,风哥通过三道基础而经典的题目,直击要害,带大家实际感受一下三种遍历最基础的写法。


首先是先序遍历。

第二题:144. 二叉树的前序遍历

关键词基础 二叉树 递归 先序遍历 模板  

风哥带你手撕算法之吃透二叉树(2)


源码

风哥带你手撕算法之吃透二叉树(2)


其次是中序遍历。

第三题:94. 二叉树的中序遍历

关键词基础 二叉树 递归 中序遍历 模板  

风哥带你手撕算法之吃透二叉树(2)


源码:

风哥带你手撕算法之吃透二叉树(2)



最后是后序遍历:

第三题:145. 二叉树的后序遍历

关键词基础 二叉树 递归 后序遍历 模板  

风哥带你手撕算法之吃透二叉树(2)风哥带你手撕算法之吃透二叉树(2)


源码



从这三题的源码中,我们可以很明显地看出,这三种遍历的源码,仅仅是

出现的位置不同,就可以极大地影响遍历的顺序,也符合我们在 中所说的二叉树遍历模板。

然而这三种遍历,具体顺序和思想如何理解?

请听下回分解。


喜欢的兄弟萌,欢迎点赞在看关注三连,老吴感激不尽。