前言
- 科研不顺啊......又不想搞了,随便弄弄吧,多花点时间刷题,今天开启二叉树!
94. 二叉树的中序遍历 - 力扣(LeetCode)
-
递归
-
# 最简单递归 class Solution: def inorderTraversal(self, root: TreeNode) -> List[int]: if not root: return [] return self.inorderTraversal(root.left) + [root.val] + self.inorderTraversal(root.right) # 前/后序就换一下顺序 # 通用模板 class Solution: def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]: res = [] # 收集结果 def dfs(root): if not root: # 访问到空结点直接返回 return # 前后序就以下换成对应顺序 dfs(root.left) # 左 res.append(root.val) # 中 dfs(root.right) # 右 dfs(root) return res
-
-
迭代
- 图和代码参考王尼玛题解
-
class Solution: def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]: res = [] stack = [] while stack or root: # 不断往左子树方向走,每走一次就将当前节点保存到栈中 # 这是模拟递归的调用 while root: # res.append(root.val) # 前/后序改到这 stack.append(root) root = root.left # 后序改成right # 当前节点为空,说明左边走到头了,从栈中弹出节点并保存 # 然后转向右边节点,继续上面整个过程 temp = stack.pop() res.append(temp.val) # 前/后序删掉 root = temp.right # 后序改成left return res # 后序的话就是[中右左]反过来,return res[::-1]
-
Morris遍历
- 过程看官解的动图
- cur无左孩子,说明到最左端:
- 加入结果,cur右移
- cur有左孩子,说明有前驱,找前驱
- 前驱无右孩:生成链接、cur左移
- 前驱有右孩:断开连接,记录cur结果,cur右移
-
class Solution: def inorderTraversal(self, root: TreeNode) -> List[int]: res = [] cur, prev = root, None while cur: if not cur.left: # 无左孩,到最左端 res.append(cur.val) # 将当前节点cur的值加入结果列表 cur = cur.right # 将当前节点指向右子树 else: prev = cur.left # 找到当前节点cur的左子树的最右节点(前驱) while prev.right and prev.right != cur: prev = prev.right if not prev.right: # 前驱无右孩 prev.right = cur # 添加连接 # res.append(cur.val) # 如果是前序,下面的加入结果改到这 cur = cur.left # 左移 else: # 前驱有右孩 prev.right = None # 断开连接 res.append(cur.val) # 将当前节点cur的值加入结果列表 cur = cur.right # 右移 return res
-
标记迭代
-
class Solution: def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]: res = [] stack = [(0, root)] # 0表示当前未访问,1表示已访问 while stack: flag, cur = stack.pop() if not cur: continue if flag == 0: stack.append((0, cur.right)) # 右 stack.append((1, cur)) # 中 stack.append((0, cur.left)) # 左 else: res.append(cur.val) return res
-
二叉树所有遍历模板总结
144. 二叉树的前序遍历 - 力扣(LeetCode)
145. 二叉树的后序遍历 - 力扣(LeetCode)
102. 二叉树的层序遍历 - 力扣(LeetCode)
-
两个列表
-
class Solution: def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]: if not root: return [] cur, res = [root], [] # cur表示当前层未访问结点,res为结果 while cur: lay, layval = [], [] # lay表示下一层该访问结点,layval表示当前层的数值列表 for node in cur: # 遍历当前层所有结点 layval.append(node.val) if node.left: lay.append(node.left) # 添加左结点到下一层 if node.right: lay.append(node.right) # 添加右结点到下一层 cur = lay # 更新下一层 res.append(layval) # 更新结果集 return res
-
-
队列BFS
-
""" # BFS模板 while queue 不空: cur = queue.pop() for 节点 in cur的所有相邻节点: if 该节点有效且未访问过: queue.push(该节点) """ class Solution: def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]: if not root: return [] res = [] # 结果 q = deque() # 队列 q.append(root) # q = deque([root]) # 直接赋值需要传入可迭代对象[] while q: vals = [] # 存当前层的值 for i in range(len(q)): # 遍历队列中(当前层)所有结点 cur = q.popleft() vals.append(cur.val) if cur.left: q.append(cur.left) if cur.right: q.append(cur.right) res.append(vals) return res
-
-
DFS递归
-
class Solution: def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]: res = [] self.level(root, 0, res) return res def level(self, root: Optional[TreeNode], level: int, res: List[List[int]]): if not root: return if len(res) == level: res.append([]) # 一直向左遍历,新增层数对应的结果列表 res[level].append(root.val) # 当前结点加入当前层的结果里去 if root.left: self.level(root.left, level+1, res) # 递归遍历左子树 if root.right: self.level(root.right, level+1, res) # 递归遍历右子树
-
589. N 叉树的前序遍历 - 力扣(LeetCode)
-
递归
-
# 简单递归 class Solution: def preorder(self, root: 'Node') -> List[int]: if not root: return temp = [] for child in root.children: temp += self.preorder(child) return [root.val] + temp # 常规递归 class Solution: def preorder(self, root: 'Node') -> List[int]: res = [] def dfs(cur): if not cur: return res.append(cur.val) for child in cur.children: # 遍历每一个子结点 dfs(child) dfs(root) return res
-
-
迭代
-
class Solution: def preorder(self, root: 'Node') -> List[int]: if not root: return res = [] s = [root] while s: cur = s.pop() res.append(cur.val) for child in cur.children[::-1]: # 从右往左添加进栈 s.append(child) # s.extend(cur.children[::-1]) # 也可以直接拼接 return res
-
590. N 叉树的后序遍历 - 力扣(LeetCode)
后言
- 今天把以上几个二叉树遍历的题目模板刷熟!这样后面的题才能信手拈来~