📌  相关文章
📜  按垂直顺序打印二叉树 |设置 3(使用水平顺序遍历)(1)

📅  最后修改于: 2023-12-03 14:54:39.983000             🧑  作者: Mango

按垂直顺序打印二叉树 | 设置 3(使用水平顺序遍历)

在二叉树的打印过程中,按照垂直顺序打印二叉树是一项非常重要的工作。它可以让我们更清晰地看到二叉树节点之间的垂直顺序。这篇文章将介绍如何按垂直顺序打印二叉树,并设置参数3使用水平顺序遍历。

水平顺序遍历

在水平顺序遍历中,按照树的层次从上到下、从左到右依次遍历每一个节点。这种遍历方式非常常见,可以应用到很多二叉树的问题中。

以下是按照水平顺序遍历输出二叉树的Python实现代码:

class Solution:
    def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
        if not root:
            return []
        
        res = []
        q = [root]
        
        while q:
            level = []
            for _ in range(len(q)):
                node = q.pop(0)
                level.append(node.val)
                if node.left: q.append(node.left)
                if node.right: q.append(node.right)
            res.append(level)
        
        return res
按垂直顺序打印二叉树
实现思路
  • 遍历整个二叉树,标记每个节点的位置
  • 找到整个二叉树的最左边节点和最右边节点的位置,确定整个二叉树的宽度
  • 遍历整个二叉树,将每个节点的值输出到相应的位置
Python实现

以下是按垂直顺序打印二叉树的Python实现代码:

class Solution:
    def printTree(self, root: Optional[TreeNode]) -> List[List[str]]:
        def get_depth(node):
            if not node:
                return 0
            return 1 + max(get_depth(node.left), get_depth(node.right))
        
        def traverse(node, depth, pos):
            if not node:
                return
            res[depth][pos] = str(node.val)
            gap = 2 ** (d - depth - 1) - 1
            if node.left:
                traverse(node.left, depth + 1, pos - gap - 1)
            if node.right:
                traverse(node.right, depth + 1, pos + gap + 1)
        
        d = get_depth(root)
        w = 2 ** d - 1
        res = [[''] * w for _ in range(d)]
        traverse(root, 0, w // 2)
        return res
示例

以下是针对二叉树 [1,2,3,null,4] 的输出示例:

         1         
       /   \       
      2     3      
       \          
        4         

输出结果为:

[["", "", "", "1", "", "", ""],
 ["", "", "2", "", "", "3", ""],
 ["", "4", "", "", "", "", ""]]
参数3使用水平顺序遍历

可以看到,上面的实现代码默认按垂直顺序打印二叉树。但是题目中要求设置参数3使用水平顺序遍历,这该怎么实现呢?可以将上面的遍历算法修改为按水平顺序遍历,实现如下:

class Solution:
    def printTree(self, root: Optional[TreeNode]) -> List[List[str]]:
        def traverse(node, depth, pos):
            if not node:
                return
            while len(res) <= depth:
                res.append([])
            res[depth].append(str(node.val))
            traverse(node.left, depth + 1, pos * 2)
            traverse(node.right, depth + 1, pos * 2 + 1)

        res = []
        traverse(root, 0, 0)
        height = len(res)
        width = 2 ** height - 1
        for i in range(height):
            res[i] = [""] * ((width - len(res[i])) // 2) + res[i] + [""] * ((width - len(res[i])) // 2)
        return res

这里对遍历算法做了较大改动。我们不再先计算整个树的宽度和深度,而是采用先序遍历的方式遍历整个树,并将节点的值存入到一个二维数组中。最后再对这个二维数组进行整理,让它成为一个类似菱形的形状。这样整个打印过程就变成了按照水平顺序遍历输出。

这里要注意的是,我们会遇到一些空节点,比如上面示例中的节点3的左右两个子节点就都是空节点。这些节点也要打印出来,不能漏掉。

示例

在使用参数3使用水平顺序遍历的前提下,针对二叉树 [1,2,3,null,4] 的输出示例结果为:

["", "1", ""]
["2", "", "3"]
["", "4", ""]
总结

通过这篇文章,我们学习了如何按垂直顺序打印二叉树,并且针对题目中的要求,实现了按照参数3使用水平顺序遍历的打印方式。同时,我们还学习了如何在二叉树打印中遍历整个二叉树,并将节点的位置信息记录下来。这是二叉树打印算法的核心思想,可以应用到很多其他的二叉树问题中。