前言:
http://t.csdnimg.cn/WzCFU(二叉树的前,中,后序递归与迭代法)
在前文中我们发现**迭代法实现的先中后序,其实风格也不是那么统一,除了先序和后序,有关联,中序完全就是另一个风格了,一会用栈遍历,一会又用指针来遍历,**很难写出统一的代码,不像是递归法,实现了其中的一种遍历方式,其他两种只要稍稍改一下节点顺序就可以了。
其实针对三种遍历方式,使用迭代法是可以写出统一风格的代码!
接下来给出统一模板下的迭代法代码及详细注释。
可能第一遍不太好理解,觉得还是之前不统一的迭代写法便于理解,但只需悟透一道(在草稿纸上跟着代码画一遍图)就吃透统一迭代法了
代码及详细注释:
迭代法前序遍历:
python
# 定义二叉树节点的类
# class TreeNode:
# def __init__(self, x):
# self.val == x
# self.left == None
# self.right == None
class Solution:
def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
if not root:
return []
stack = [root] # 使用栈来辅助进行遍历 把根节点root放入堆中
res = [] # 用于存放前序遍历的结果
while stack:
node = stack.pop() # 弹出栈顶节点
if node:
if node.right:
stack.append(node.right) # 先将右子节点压入栈中
if node.left:
stack.append(node.left) # 再将左子节点压入栈中
stack.append(node) # 最后将当前节点压入栈中
stack.append(None) # 压入一个空节点作为标记
else:
node = stack.pop() # 如果弹出的是空节点,说明当前节点已经遍历过了,可以将其值加入结果中
res.append(node.val)
return res # 返回前序遍历的结果
迭代法中序遍历:
python
# 定义二叉树节点的类
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
if not root: # 根节点为空 返回[]
return []
res = [] # 用于存放中序遍历的结果
stack = [root] # 使用栈来辅助进行遍历 把root(根节点的值)加入到栈中
while stack:
node = stack.pop() # 弹出栈顶节点
if node:
if node.right:
stack.append(node.right) # 先将右子节点压入栈中
stack.append(node) # 再将当前节点压入栈中
stack.append(None) # 压入一个空节点作为标记
if node.left:
stack.append(node.left) # 最后将左子节点压入栈中
else:
node = stack.pop() # 如果弹出的是空节点,说明当前节点已经遍历过了,可以将其值加入结果中
res.append(node.val)
return res # 返回中序遍历的结果
迭代法后序遍历:
python
# 定义二叉树节点的类
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
if not root:
return []
res = [] # 用于存放后序遍历的结果
stack = [root] # 使用栈来辅助进行遍历
while stack:
node = stack.pop() # 弹出栈顶节点
if node:
stack.append(node) # 将当前节点压入栈中
stack.append(None) # 压入一个空节点作为标记
if node.right:
stack.append(node.right) # 先将右子节点压入栈中
if node.left:
stack.append(node.left) # 再将左子节点压入栈中
else:
node = stack.pop() # 如果弹出的是空节点,说明当前节点已经遍历过了,可以将其值加入结果中
res.append(node.val)
return res # 返回后序遍历的结果