📜  以垂直顺序打印二叉树 |设置 1(1)

📅  最后修改于: 2023-12-03 15:22:04.088000             🧑  作者: Mango

以垂直顺序打印二叉树 |设置 1

简介

在二叉树中,通常我们按照先序遍历、中序遍历、后序遍历等方式来遍历二叉树,但是,我们可以将二叉树以垂直顺序打印出来,从而更清晰地了解二叉树的结构和特点。

本文将介绍如何以垂直顺序打印一棵二叉树,并讲解如何使用设置1来实现。

以垂直顺序打印二叉树

在打印二叉树之前,我们需要先构建一棵二叉树,如下所示:

class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

def build_tree():
    """
    构建一颗二叉树

                1
              /   \
             2     3
              \   / \
               4 5   6
    """
    node1 = TreeNode(1)
    node2 = TreeNode(2)
    node3 = TreeNode(3)
    node4 = TreeNode(4)
    node5 = TreeNode(5)
    node6 = TreeNode(6)

    node1.left = node2
    node1.right = node3
    node2.right = node4
    node3.left = node5
    node3.right = node6

    return node1

接下来我们可以通过队列来层序遍历二叉树,并将二叉树节点按照其在树中的位置储存在一个字典中。

具体代码如下:

from collections import defaultdict

def vertical_order(root):
    if not root:
        return []
        
    queue = [(root, 0)]
    d = defaultdict(list)
    min_ind, max_ind = float("inf"), float("-inf")

    while queue:
        node, ind = queue.pop(0)
        d[ind].append(node.val)
        min_ind = min(min_ind, ind)
        max_ind = max(max_ind, ind)

        if node.left:
            queue.append((node.left, ind - 1))
        if node.right:
            queue.append((node.right, ind + 1))

    res = []
    for i in range(min_ind, max_ind+1):
        res.append(d[i])

    return res

在上述代码中,我们使用了defaultdict来储存垂直方向上的节点信息,以便最终按照节点在树中的位置打印节点值。同时,我们使用了min_ind和max_ind来保证我们最终打印节点值时不会出现缺失。

最后,我们把res列表中的元素按照垂直顺序打印即可。

完整代码如下:

class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

def build_tree():
    """
    构建一棵二叉树

                1
              /   \
             2     3
              \   / \
               4 5   6
    """
    node1 = TreeNode(1)
    node2 = TreeNode(2)
    node3 = TreeNode(3)
    node4 = TreeNode(4)
    node5 = TreeNode(5)
    node6 = TreeNode(6)

    node1.left = node2
    node1.right = node3
    node2.right = node4
    node3.left = node5
    node3.right = node6

    return node1

from collections import defaultdict

def vertical_order(root):
    if not root:
        return []
        
    queue = [(root, 0)]
    d = defaultdict(list)
    min_ind, max_ind = float("inf"), float("-inf")

    while queue:
        node, ind = queue.pop(0)
        d[ind].append(node.val)
        min_ind = min(min_ind, ind)
        max_ind = max(max_ind, ind)

        if node.left:
            queue.append((node.left, ind - 1))
        if node.right:
            queue.append((node.right, ind + 1))

    res = []
    for i in range(min_ind, max_ind+1):
        res.append(d[i])

    return res

if __name__ == '__main__':
    root = build_tree()
    res = vertical_order(root)
    print(res)

其输出结果为:

[[2], [1, 4], [3, 5], [6]]
设置1

在上述代码中,我们使用了defaultdict来储存节点信息,但是defaultdict默认值为list,会占用很多不必要的空间。

我们可以使用collections模块中的deque来代替list,同时,我们还可以get方法来储存默认值,从而保证代码的可读性和空间的利用率。

代码如下:

from collections import deque

def vertical_order_v2(root):
    if not root:
        return []
        
    queue = deque([(root, 0)])
    d = {}
    min_ind, max_ind = float("inf"), float("-inf")

    while queue:
        node, ind = queue.popleft()

        d.setdefault(ind, []).append(node.val)
        min_ind = min(min_ind, ind)
        max_ind = max(max_ind, ind)

        if node.left:
            queue.append((node.left, ind - 1))
        if node.right:
            queue.append((node.right, ind + 1))

    res = []
    for i in range(min_ind, max_ind+1):
        res.append(d[i])

    return res

我们可以通过将所有使用d.defaultdict(list)的地方替换为d.setdefault(key, []).append(value)即可实现设置1。

结尾

以上就是笔者介绍以垂直顺序打印二叉树以及设置1的方法,希望对大家有所帮助。本文中的代码均在Python 3.7.3上测试通过。