打印二叉树边界节点

打印二叉树边界节点

二叉树节点

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

    def is_leaf(self):
        return self.left is None and self.right is None

题目

给定一棵二叉树根节点root,逆时针打印该二叉树的边界节点,边界节点的定义:

标准一

  • 根节点为边界节点
  • 叶子节点为边界节点
  • 如果节点在它所在层最左或最右端,也为边界节点

思路

先序遍历过程中记录当前节点的层级,若当前节点最左边界尚未设置,则设置;若发现当前层新的节点,更新右边界节点。

实现

def height(node, level):
    if node is None:
        return level
    return max(height(node.left, level+1), height(node.right, level+1))


def get_edge_nodes1(root):
    def set_edge_map(node, level):
        if node is None:
            return

        if (level, 'left') not in edge_map:
            edge_map[(level, 'left')] = node
        edge_map[(level, 'right')] = node
        set_edge_map(node.left, level+1)
        set_edge_map(node.right, level+1)

    def get_leaf_nodes_not_in_map(node, level):
        if node is None:
            return
        if node.is_leaf() and (node != edge_map[(level, 'left')] and
           node != edge_map[(level, 'right')]):
            result.append(node.val)

        get_leaf_nodes_not_in_map(node.left, level+1)
        get_leaf_nodes_not_in_map(node.right, level+1)

    result = []
    if root is None:
        return result

    max_level = height(root, 0)
    edge_map = {}
    set_edge_map(root, 0)

    # left edge nodes
    for level in range(max_level):
        result.append(edge_map[(level, 'left')].val)

    # leaf nodes
    get_leaf_nodes_not_in_map(root, 0)

    # right edge nodes
    for level in reversed(range(max_level)):
        if edge_map[(level, 'right')] != edge_map[(level, 'left')]:
            result.append(edge_map[(level, 'right')].val)

    return result

标准二

  • 根节点为边界节点
  • 叶子节点为边界节点
  • 树左边界延伸下去的路径为边界节点
  • 树右边界延伸下去的路径为边界节点

思路

从根节点开始往下寻找第一个既有左子树,又有右子树的节点node,此前的节点都满足条件;
从node左子树打印左边界的延伸路径,从node右子树打印右边界的延伸路径。

实现

def get_edge_nodes2(root):
    def get_left_edge(node, flag):
        if node is None:
            return

        if flag or node.is_leaf():
            result.append(node.val)

        get_left_edge(node.left, flag)
        get_left_edge(node.right, flag and node.left is None)

    def get_right_edge(node, flag):
        if node is None:
            return

        get_right_edge(node.left, flag and node.right is None)
        get_right_edge(node.right, flag)

        if flag or node.is_leaf():
            result.append(node.val)

    if root is None:
        return

    result = [root.val]
    if root.left is not None and root.right is not None:
        get_left_edge(root.left, True)
        get_right_edge(root.right, True)
    else:
        node = root.left if root.left is not None else root.right
        get_edge_nodes2(node)

    return result

测试

def test_get_edge_nodes():
    nodes = [TreeNode(i) for i in range(17)]
    root = nodes[1]
    nodes[1].left, nodes[1].right = nodes[2], nodes[3]
    nodes[2].right = nodes[4]
    nodes[4].left, nodes[4].right = nodes[7], nodes[8]
    nodes[8].right = nodes[11]
    nodes[11].left, nodes[11].right = nodes[13], nodes[14]

    nodes[3].left, nodes[3].right = nodes[5], nodes[6]
    nodes[5].left, nodes[5].right = nodes[9], nodes[10]
    nodes[9].left = nodes[12]
    nodes[12].left, nodes[12].right = nodes[15], nodes[16]

    result1 = get_edge_nodes1(root)
    print(result1)

    result2 = get_edge_nodes2(root)
    print(result2)


if __name__ == '__main__':
    test_get_edge_nodes()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值