二叉树前/中/后序迭代算法 - Python3
参考链接
说明
本文不含递归代码,只介绍手写堆栈(迭代)方式。代码中变量 p 表示 当前用于向下探索的结点,变量 x 表示 当前从栈中弹出、当前要处理/访问的结点。
前序、中序大多是 pop() 就访问,后序往往要晚一点。
代码整理
中序
class Solution:
def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
if not root: return []
res = []
stk = [] # 弹出和访问永远在一起,所以我们用p来探索root,而不是直接把root放入栈
p = root # p表示当前准备继续向左下探索的节点
while p or stk:
# 阶段1:一路向左,将路径上的所有节点压栈
#(宏观上既压入了左又压入了根,只要入了栈,都会在阶段2访问到)
while p:
stk.append(p)
p = p.left
# 阶段2:弹出栈顶节点并访问
x = stk.pop() # 注意这里是x,不再是p
res.append(x.val)
# 阶段3:转向右子树,继续循环
# (弹出的x同时,判断有没有右子树,有则又需要以x.right为“根”,进行一系列的压栈)
if x.right:
p = x.right
return res
前序/先序
class Solution:
def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
if not root: return []
res = []
stk = [root] # 弹出和访问永远一起,我们第一步就可以直接弹出root并访问root
while stk:
x = stk.pop()
res.append(x.val)
if x.right:
stk.append(x.right) # 入栈先右后左,则出栈先左后右
if x.left:
stk.append(x.left)
return res
后序
双栈法
class Solution:
def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
if not root: return []
tmp = [] # 中间过渡,中右左
stk = [root]
# 类似先序(中左右),但改为中右左
while stk:
x = stk.pop()
tmp.append(x.val)
if x.left:
stk.append(x.left)
if x.right:
stk.append(x.right)
# 将tmp取反即可
res = []
while tmp:
res.append(tmp.pop())
return res
标记法
class Solution:
def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
if not root: return []
res = []
stk = [(root, False)] # 记录是否visited
while stk:
x, visited = stk.pop()
if not visited:
stk.append((x, True))
if x.right: stk.append((x.right, False))
if x.left: stk.append((x.left, False))
else:
res.append(x.val)
return res
浙公网安备 33010602011771号