前置条件
给定一个链表形式实现的二叉树分别使用递归和非递归的方式遍历二叉树
- 前序遍历
- 递归
复习:递归的三要素
- 递归的终止条件(节点为空)
- 每层递归的输入和输出(输入是当前的二叉树,输出是前序遍历的节点顺序)
- 递归内的处理逻辑(按照中左右遍历节点)
def preorderTraversal(root: Optional[TreeNode]) -> List[int]: # 递归函数的输入是当前二叉树 输出是前序遍历的节点顺序 if not root : # 递归终止条件 return [] return [root.val] + self.preorderTraversal(root.left) + self.preorderTraversal(root.right) # 递归内的处理逻辑 中左右
- 非递归
非递归方式采用栈实现,先将根节点压入栈,出栈,再将右孩子节点入栈,左孩子节点入栈,因为栈的先入后出特性,所以按照中右左进栈
def preorderTraversal(root: Optional[TreeNode]) -> List[int]: if not result: return [] # 二叉事是否为空 stack = result = [] stack.append(root) while stack: cur = stack.pop() # 先处理中间节点 result.append(cur.val) if cur.right: # 然后压入右节点 stack.append(cur.left) if cur.left: # 最后压入左节点 stack.append(cur.right) return result
- 递归
- 中序
- 递归
def inorderTraversal(root: Optional[TreeNode]) -> List[int]: if not root: return [] return self.inorderTraversal(root.left) + [root.val] + self.inorderTraversal(root.right) # 递归内的处理逻辑 左中右
- 非递归
def inorderTraversal(root: Optional[TreeNode]) -> List[int]: result = [] stack = [] while root or stack: if root: stack.append(root) root = root.left else: cur = stack.pop() result.append(cur.val) root = cur.right return result
- 后序
- 递归
def postorderTraversal(root: Optional[TreeNode]) -> List[int]: if not root: return [] return self.postorderTraversal(root.left) + self.postorderTraversal(root.right) + [root.val]
- 非递归
三次经过中间节点,先一直往左子树遍历,再转向右子树,最后读取中间节点
后序遍历是左右中,前序遍历是中左右,将前序遍历稍加改造,变成中右左,再倒序输出def postorderTraversal(root: Optional[TreeNode]) -> List[int]: if not root: return [] result = [] stack = [] node = root while node or stack: while node: stack.append(node) if node.left: # 先一直往左走 node = node.left else: # 不能往左走就转向右 node = node.right cur = stack.pop() # 此时一定是叶子节点 读取 result.append(cur.val) if stack and stack[-1].left == cur: # 判断是否遍历过右子树 node = stack[-1].right else: node = None return result
def postorderTraversal(root: Optional[TreeNode]) -> List[int]: if not root: return [] stack = [] result = [] stack.append(root) while stack: cur = stack.pop() result.append(cur.val) if cur.left: # 先压入左节点 stack.append(cur.left) if cur.right: # 再压入右节点 stack.append(cur.right) return result[::-1] # 中右左 -> 左右中