(代码随想录自用笔记)
层序遍历一个二叉树,需要借用一个辅助数据结构,即队列来实现,队列先进先出,符合一层一层遍历的逻辑,而用栈先进后出适合模拟深度优先遍历也就是递归的逻辑。
而这种层序遍历方式就是图论中的广度优先遍历,只不过我们应用在二叉树上。
使用队列实现二叉树广度优先遍历,动画如下:
首先检查根节点是否为空,如果为空则直接返回空列表。使用一个队列来存储待访问的节点,初始时只有根节点在队列中。然后,通过一个外层循环遍历每一层,内层循环用于遍历当前层的所有节点,将它们的值存储到一个列表中,并将它们的非空子节点加入队列中以便于后续遍历。每一层遍历结束后,将该层的节点值列表加入到最终的结果列表中。
from collections import deque
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
def levelOrderTraversal(root: TreeNode) -> List[List[int]]:
# 如果根节点为空,则返回空列表
if not root:
return []
# 使用deque创建队列,首先将根节点加入队列
queue = deque([root])
# 结果列表
result = []
# 当队列不为空时,循环执行
while queue:
"""
不断更新当前层的节点数,初始时加入了根节点,即当前层节点数为1
后续会加入根节点的左右孩子,重新计算当前层节点数,控制内层循环的次数
"""
# 当前层节点数
level_size = len(queue)
# 存储当前层的节点值
level_nodes = []
# 遍历当前层的所有节点
for _ in range(level_size):
# 从队列中弹出一个节点
node = queue.popleft()
# 将该节点的值加入当前层的节点值列表中
level_nodes.append(node.val)
# 如果该节点的左子节点存在,将其加入队列中
if node.left:
queue.append(node.left)
# 如果该节点的右子节点存在,将其加入队列中
if node.right:
queue.append(node.right)
# 将当前层的节点值列表加入结果列表中
result.append(level_nodes)
# 返回结果列表
return result
【 deque()函数】
deque
是 Python 中 collections
模块提供的一个类,全称为 "double-ended queue",即双端队列。双端队列支持从两端进行添加和删除元素的操作,因此它非常适用于需要从两端修改数据的情况,比如在树的层序遍历中作为队列使用,或者实现栈、队列等数据结构。
可以在创建时直接用一个可迭代对象(如列表)初始化 deque
:
queue = deque([1, 2, 3]) # 创建一个包含1, 2, 3的deque
deque
提供了多种方法来操作双端队列,包括但不限于:
append(x)
: 从右端添加元素x
到双端队列。appendleft(x)
: 从左端添加元素x
到双端队列。pop()
: 移除并返回双端队列的最右端元素。popleft()
: 移除并返回双端队列的最左端元素