返回

二叉树层序遍历:探秘广度优先搜索的巧妙运用

前端

层序遍历:纵横二叉树的逐层探秘之旅

什么是二叉树层序遍历?

层序遍历是一种探索二叉树的算法,它以广度优先的方式,逐层遍历树中的节点。它从根节点开始,遍历完一层的所有节点后再深入到下一层,如此层层深入,直到遍历完整棵树。

广度优先搜索:逐层推进,层层深入

层序遍历采用广度优先搜索(BFS)算法,它使用队列(queue)来存储待遍历的节点。队列遵循先进先出(FIFO)的原则,这意味着先加入队列的节点会被优先访问。BFS以根节点为起点,将根节点加入队列,然后依次访问队列中的第一个节点,并将该节点的子节点加入队列中。这种方式确保了我们在遍历完一层的所有节点后,再开始遍历下一层。

队列:存储待遍历节点的利器

队列是一种先进先出(FIFO)的数据结构,它允许我们在队列的一端添加元素,而在另一端删除元素。队列的特性非常适合层序遍历,因为它可以保证我们按层级顺序访问二叉树中的节点。

代码实例:清晰呈现层序遍历的步骤

为了更深入地理解层序遍历算法,让我们通过一个代码实例来演示它的工作原理:

def level_order_traversal(root):
  """
  层序遍历二叉树

  Args:
    root: 二叉树的根节点

  Returns:
    一个包含二叉树各层节点值列表的列表
  """

  # 定义一个队列来存储待遍历的节点
  queue = [root]

  # 初始化结果列表,用于存储各层节点值
  result = []

  # 遍历队列
  while queue:
    # 获取当前层的节点数
    level_size = len(queue)

    # 创建一个列表来存储当前层的节点值
    level_values = []

    # 遍历当前层的节点
    for _ in range(level_size):
      # 获取并删除队列中的第一个节点
      node = queue.pop(0)

      # 将节点值添加到当前层的节点值列表中
      level_values.append(node.val)

      # 将节点的左子节点和右子节点添加到队列中
      if node.left:
        queue.append(node.left)
      if node.right:
        queue.append(node.right)

    # 将当前层的节点值列表添加到结果列表中
    result.append(level_values)

  # 返回结果列表
  return result

层序遍历的妙用

层序遍历算法在计算机科学领域有着广泛的应用,包括:

  • 计算二叉树的高度
  • 寻找二叉树的最大宽度
  • 判断二叉树是否为完全二叉树
  • 构建二叉树的层次结构
  • 查找二叉树中特定元素

常见问题解答

Q1:为什么层序遍历使用队列而不是栈?

A1:队列遵循先进先出的原则,它可以确保我们先遍历完一层的节点,再开始遍历下一层的节点。而栈遵循后进先出的原则,这会导致我们先遍历完一层的右侧节点,再遍历左侧节点。

Q2:层序遍历的时间复杂度是多少?

A2:层序遍历的时间复杂度为 O(n),其中 n 是二叉树中的节点数。

Q3:层序遍历的空间复杂度是多少?

A3:层序遍历的空间复杂度为 O(w),其中 w 是二叉树中最宽的一层的节点数。

Q4:如何使用层序遍历判断二叉树是否为完全二叉树?

A4:在层序遍历过程中,如果我们遇到一个节点的右子节点存在而左子节点不存在,或者我们遇到一个节点既没有左子节点也没有右子节点,那么二叉树不是完全二叉树。

Q5:层序遍历算法可以修改为深度优先遍历吗?

A5:是的,我们可以使用栈来代替队列,将算法修改为深度优先遍历。深度优先遍历会沿着一条路径深入到树中,直到无法再深入,然后再回退到上一层。