风哥带你手撕算法之吃透二叉树(2)
程序员吴乘风。
本篇 LeetCode 题目列表:
114. 二叉树展开为链表
144. 二叉树的前序遍历
94. 二叉树的中序遍历
145. 二叉树的后序遍历
上一篇文章,风哥简要介绍了 模板思维 , 递归思想 以及手撕第一道二叉树算法题。
今天我将带大家继续攻破二叉树经典题,并且附上详细解题思路。
一、算法实战
第一题:114. 二叉树展开为链表
关键词:二叉树 递归 原地
这题的主要目标,就是将二叉树变成一个按 先序遍历 顺序存储节点的 链表 ,并且要 原地 。
原地,简单来说就是不依赖或依赖少数的额外资源,仅依靠输出来覆盖输入的一种算法操作。
在这题中的体现,就是不要通过外部容器(额外数组、链表等)进行转存,仅通过将二叉树左节点转移到右节点的操作,将二叉树变成一个 root.left = null 的链表。
思路:
我们可以依次遍历 6 5 4 3 2 1 ,这个顺序就是 先序遍历的逆序 ,即“右 -> 左 -> 中”。
而后序遍历与这种模式最接近,即"左 -> 右 -> 中":先进入当前节点的左子树,再进入当前节点的右子树,最后再对当前节点进行操作,模板即我们在上一篇提到的:
所以我们对其改造,变成这一题我们所需要的遍历顺序:逆先序遍历“右 -> 左 -> 中”:先进入当前节点的右子树,再进入当前节点的左子树,最后再对当前节点进行操作,模板如下:
知道了遍历顺序,接下来我们要做的,就是按照顺序,将 6 接到上一级节点 5 的右子树位置, 5 接到上一级节点 4 的位置...以此类推。
这样,就可以依题意得到先序遍历链表了,是不是很简单?
这里的话,利用一个全局变量 pre,更新当前根节点的右指针为 pre,左指针为 null。
源码:
左子树一定要记得置空、删除。
心得:
熟记二叉树遍历模板,在遇到具体问题时需灵活变通,适当使用各种遍历的逆序以及变种。
接下来,对于之前反反复复提到的先序遍历、中序遍历、后序遍历,风哥通过三道基础而经典的题目,直击要害,带大家实际感受一下三种遍历最基础的写法。
首先是先序遍历。
第二题:144. 二叉树的前序遍历
关键词:基础 二叉树 递归 先序遍历 模板
源码:
其次是中序遍历。
第三题:94. 二叉树的中序遍历
关键词:基础 二叉树 递归 中序遍历 模板
源码:
最后是后序遍历:
第三题:145. 二叉树的后序遍历
关键词:基础 二叉树 递归 后序遍历 模板
源码:
从这三题的源码中,我们可以很明显地看出,这三种遍历的源码,仅仅是
出现的位置不同,就可以极大地影响遍历的顺序,也符合我们在 中所说的二叉树遍历模板。
然而这三种遍历,具体顺序和思想如何理解?
请听下回分解。
喜欢的兄弟萌,欢迎点赞在看关注三连,老吴感激不尽。