前言
在看到Mirrors前序遍历方法时,非常的头疼,不知所云种种,经过一番磨砺,搞清楚了,至少明白了Mirros遍历想说什么了。其实这个名字会带给人很大的误差,其核心思想是建立一个可以往回走的“梯子”,因而需要提前“搭”好往返使用的梯子,而且用完后则及时“拆掉”梯子。哈哈,是不是很懵,下面我将详细叙说一下。
提示:以下是本篇文章正文内容,下面案例可供参考
一、问题描述
一个数组的前序遍历,即 先根节点 -> 左子树 -> 右子树。这里就不过多赘述,图示及代码详解在后续部分。
二、解题思路及代码
1.整体代码
以下为整体代码,按照while循环中的前四次来对“搭梯子”与“拆梯子”进行了解。
Mirrors 前序遍历
res = list()
if root is None: return []
p1 = root
while p1:
# 一鼓作气 找到最左面
if p1.left is None:
res.append(p1.val)
p1 = p1.right
else:
p2 = p1.left
while p2.right and p2.right != p1:
p2 = p2.right
if p2.right is None:
res.append(p1.val)
p2.right = p1
p1 = p1.left
else:
p2.right = None
p1 = p1.right
return res
2.搭梯子
使用的程序段为:
if p2.right is None:
res.append(p1.val)
p2.right = p1
p1 = p1.left
第一次循环,用来搭梯子,p2指针将节点5的右指针指向p1现在所处的位置,即节点1。
第二次循环,亦是搭梯子,p2指针将节点4的右指针指向p1现在所处的位置,即节点2。
3.爬梯子
使用的程序段为:
if p1.left is None:
res.append(p1.val)
p1 = p1.right
第三次循环,用来搭梯子往上走,p1指针通过节点4的右节点回到节点2。
4.拆梯子
使用的程序段为:
else:
p2.right = None
p1 = p1.right
第四次循环,梯子使用后拆梯子,p2.right 为空,拆掉梯子。
三、总结
这道题挺有趣的,其思想便是不断地构建子数与前驱节点的通道,并在使用后关闭通道,这种方法非常地节省内存开销,不过时间复杂度上并没有什么缩减,且就理解而言颇费劲,在此做一下记录,理解其中的精髓,代码可以适当记一下,不够遇到二叉树,还是递归 ~ 香啊!!!