前言:
http://t.csdnimg.cn/WzCFU(二叉树的前,中,后序递归与迭代法)
在前文中我们发现迭代法实现的先中后序,其实风格也不是那么统一,除了先序和后序,有关联,中序完全就是另一个风格了,一会用栈遍历,一会又用指针来遍历,很难写出统一的代码,不像是递归法,实现了其中的一种遍历方式,其他两种只要稍稍改一下节点顺序就可以了。
其实针对三种遍历方式,使用迭代法是可以写出统一风格的代码!
接下来给出统一模板下的迭代法代码及详细注释。
可能第一遍不太好理解,觉得还是之前不统一的迭代写法便于理解,但只需悟透一道(在草稿纸上跟着代码画一遍图)就吃透统一迭代法了
代码及详细注释:
迭代法前序遍历:
# 定义二叉树节点的类
# class TreeNode:
# def __init__(self, x):
# self.val == x
# self.left == None
# self.right == Noneclass 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 # 返回前序遍历的结果
迭代法中序遍历:
# 定义二叉树节点的类
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = rightclass 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 # 返回中序遍历的结果
迭代法后序遍历:
# 定义二叉树节点的类
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = rightclass 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 # 返回后序遍历的结果