二叉树的遍历是算法和数据结构中的核心概念。以下是四种基本的二叉树遍历方法:
前序遍历(Preorder):根 -> 左 -> 右
中序遍历(Inorder):左 -> 根 -> 右
后序遍历(Postorder):左 -> 右 -> 根
层序遍历(Level Order):按树的层次从上到下、从左到右
递归遍历
(1)前序遍历:根、左、右
递归三部曲:
- 确定递归函数的参数和返回值:因为要打印出前序遍历节点的数值,所以参数里需要传入res来放节点的数值,除了这一点就不需要再处理什么数据了也不需要有返回值,所以递归函数返回类型就是void
- 确定终止条件:在递归的过程中,如何算是递归结束了呢,当然是当前遍历的节点是空了,那么本层递归就要结束了,所以如果当前遍历的这个节点是空,就直接return。
- 确定单层递归的逻辑:前序遍历是中左右的顺序,所以在单层递归的逻辑,是要先取中节点的数值。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
res = []
def preorder(root):
if root is None:
return
res.append(root.val)
preorder(root.left)
preorder(root.right)
preorder(root)
return res
(2)中序遍历:左、根、右
# Definition for a binary tree node.
# 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]:
res = []
def inorder(root):
if root is None:
return
inorder(root.left)
res.append(root.val)
inorder(root.right)
inorder(root)
return res
(3)后序遍历:左、右、根
class Solution:
def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
# 左右根
result = []
def houxu(root):
if root is None:
return
houxu(root.left)
houxu(root.right)
result.append(root.val)
houxu(root)
return result
层序遍历
102.层序遍历
易错点:
- 空列表[]和空队列deque([])都是有效的对象,只是它们内部没有元素。它们不是None,而是具体的空数据结构实例。(所以while q 写成 while q is not None是错误的)
- 空队列和空列表的布尔值:在布尔上下文中,空队列deque([])和空列表同样被视为False。
时空复杂度:
- 时间复杂度:O(n)——每个节点遍历一次
- 空间复杂度:O(n)——满二叉树(每一层都填满)最后一层有大约 n/2 个节点,因此队列中最多有 O(n) 个元素,所以空间复杂度是 O(n) 的。
class Solution:
def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
if root is None:
return []
ans = []
q = deque([root])
while q:
vals = []
for _ in range(len(q)):
node = q.popleft()
vals.append(node.val)
if node.left: q.append(node.left)
if node.right: q.append(node.right)
ans.append(vals)
return ans
107.二叉树的层序遍历2
在层序遍历的基础上加一个res[::-1]即可。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def levelOrderBottom(self, root: Optional[TreeNode]) -> List[List[int]]:
if not root:
return []
q = deque([root])
res = []
while q:
n = len(q)
ans = []
for _ in range(n):
node = q.popleft()
if node.left:
q.append(node.left)
if node.right:
q.append(node.right)
ans.append(node.val)
res.append(ans)
return res[::-1]
199.二叉树的右视图
在层序遍历的基础上加一个res[::-1]即可。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def rightSideView(self, root: Optional[TreeNode]) -> List[int]:
if root is None:
return []
ans = []
q = deque([root])
while q:
vals = []
for _ in range(len(q)):
node = q.popleft()
vals.append(node.val)
if node.left: q.append(node.left)
if node.right: q.append(node.right)
ans.append(vals)
return [s[-1] for s in ans]
637.二叉树的层平均值
在层序遍历的基础上加一个[sum(s)/len(s) for s in ans] 即可。
class Solution:
def averageOfLevels(self, root: Optional[TreeNode]) -> List[float]:
if root is None:
return []
ans = []
q = deque([root])
while q:
vals = []
for _ in range(len(q)):
node = q.popleft()
vals.append(node.val)
if node.left: q.append(node.left)
if node.right: q.append(node.right)
ans.append(vals)
return [sum(s)/len(s) for s in ans]
429.N叉树的层序遍历
遍历左右子树改为:if node.children: for i in node.children: q.append(i)
"""
# Definition for a Node.
class Node:
def __init__(self, val: Optional[int] = None, children: Optional[List['Node']] = None):
self.val = val
self.children = children
"""
class Solution:
def levelOrder(self, root: 'Node') -> List[List[int]]:
if root is None:
return []
ans = []
q = deque([root])
while q:
vals = []
for _ in range(len(q)):
node = q.popleft()
vals.append(node.val)
if node.children:
for i in node.children:
q.append(i)
ans.append(vals)
return ans
515.每棵树中最大值
class Solution:
def largestValues(self, root: Optional[TreeNode]) -> List[int]:
if root is None:
return []
ans = []
q = deque([root])
while q:
vals = []
for _ in range(len(q)):
node = q.popleft()
vals.append(node.val)
if node.left: q.append(node.left)
if node.right: q.append(node.right)
ans.append(vals)
return [max(i) for i in ans]
116.填充每个节点的下一个右侧节点指针
这里易错的是,要return root,不能return []。因为题目要求返回的是一个节点形式的。
"""
# Definition for a Node.
class Node:
def __init__(self, val: int = 0, left: 'Node' = None, right: 'Node' = None, next: 'Node' = None):
self.val = val
self.left = left
self.right = right
self.next = next
"""
class Solution:
def connect(self, root: 'Optional[Node]') -> 'Optional[Node]':
if root is None:
return root # return []
# ans = []
q = deque([root])
while q:
# vals = []
pre = None # 修改处
for _ in range(len(q)):
node = q.popleft()
if pre:
pre.next = node
pre = node
# vals.append(node)
if node.left: q.append(node.left)
if node.right: q.append(node.right)
# ans.append(vals)
return root # 修改处
104.二叉树的最大深度
也是用模板
class Solution:
def maxDepth(self, root: Optional[TreeNode]) -> int:
if root is None:
return 0 # 修改处
ans = []
q = deque([root])
while q:
vals = []
for _ in range(len(q)):
node = q.popleft()
vals.append(node.val)
if node.left: q.append(node.left)
if node.right: q.append(node.right)
ans.append(vals)
return len(ans) # 修改处
111.二叉树的最小深度
class Solution:
def minDepth(self, root: TreeNode) -> int:
if not root:
return 0
depth = 0
queue = deque([root])
while queue:
depth += 1
for _ in range(len(queue)):
node = queue.popleft()
if not node.left and not node.right:
return depth
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
return depth