返回

从上到下打印二叉树 III:层层递进,探寻二叉树的别样风采

Android

探索「剑指 Offer」系列:逐层揭秘二叉树的打印奥秘

层层推进,深入二叉树的迷宫

二叉树是一种广泛应用于数据存储和处理的常见数据结构,它以其独特的层级关系和高效的检索特性著称。在「剑指 Offer」系列算法题中,「剑指 Offer 32-III.从上到下打印二叉树III」一题便要求我们以一种特定的「层层递进」方式打印二叉树,为我们揭开了二叉树处理的另一重神秘面纱。

逐层深入,领略二叉树的独特风采

本题的关键在于以特定的顺序打印二叉树:

  • 第一层:从左到右打印
  • 第二层:从右到左打印
  • 第三层:从左到右打印
  • 以此类推

如此这般,一层层铺展,勾勒出二叉树的别样轮廓。

算法解析,巧妙运用双端队列

要实现如此别致的打印效果,需要借助巧妙的算法设计。我们将采用广度优先搜索(BFS)算法,结合双端队列(Deqeue)巧妙地实现「层层递进」的打印效果。

广度优先搜索,层级探索

广度优先搜索算法以层级为单位,层层探索二叉树的结点,每一层结点都依次入队,再依次出队。当一层结点全部出队后,再处理其子结点。

双端队列,交替使用

双端队列兼具先进先出(FIFO)和先进后出(LIFO)特性。第一层采用先进先出方式,即从队首入队出队;第二层采用先进后出方式,即从队尾入队出队。以此交替使用,便可实现「层层递进」的打印效果。

代码实现,精雕细琢

def levelOrder(self, root: TreeNode) -> list[list[int]]:
    if not root:
        return []
    res = []
    queue = [root]
    left_to_right = True

    while queue:
        level = []
        size = len(queue)
        for _ in range(size):
            if left_to_right:
                node = queue.pop(0)
                level.append(node.val)
            else:
                node = queue.pop()
                level.append(node.val)
            if node.left:
                queue.append(node.left)
            if node.right:
                queue.append(node.right)
        res.append(level)
        left_to_right = not left_to_right
    return res

范例演练,印证正解

设有一棵二叉树:

          1
        / \
       2   3
      / \
     4   5

算法执行过程:

  • 第一层:从左到右打印,结果为:[1]
  • 第二层:从右到左打印,结果为:[3, 2]
  • 第三层:从左到右打印,结果为:[4, 5]

常见问题解答

  1. 为什么使用广度优先搜索算法?

    • 广度优先搜索算法可以逐层探索二叉树,符合题目中「层层递进」的要求。
  2. 为什么使用双端队列?

    • 双端队列可以同时支持先进先出和先进后出特性,满足不同层级的打印顺序需求。
  3. 如何确定打印方向?

    • 通过布尔变量 left_to_right 标记当前层级的打印方向。
  4. 如何处理空树的情况?

    • 如果二叉树为空,则直接返回空列表。
  5. 打印的结点值是如何获取的?

    • 对于每一层,我们将依次访问每一结点,并将结点的值添加到 level 列表中。

结语

「剑指 Offer」系列算法题妙趣横生,为我们提供了一次次挑战自我、锻炼思辨的良机。通过层层递进的打印方式,我们领略到了二叉树的独特风采,也加深了对数据处理和算法设计的理解。愿各位求知者在算法的迷宫中继续探险,解锁更多的技术瑰宝!