python 中二叉树的顶视图

Top view of a Binary tree in python

我正在尝试解决 geeksforgeeks.com

上的 top view of the binary tree 问题

Given below is a binary tree. The task is to print the top view of binary tree. Top view of a binary tree is the set of nodes visible when the tree is viewed from the top. For the given below tree

      1
   /    \
  2      3
 / \    / \
4   5  6   7

Top view will be: 4 2 1 3 7

Note: Return nodes from leftmost node to rightmost node.

谁能告诉我我的代码哪里错了?它适用于我尝试过的大多数情况,但对于太长而无法干燥的情况则失败了 运行.

class Solution:
  
    #Function to return a list of nodes visible from the top view 
    #from left to right in Binary Tree.

    def topView(self,root):
        left_ans = []
        def left_view(root,level) :
            if not root : return 
            if level > len(left_ans) : left_ans.append(root.data)
            left_view(root.left,level+1)
            left_view(root.right,level-1)
        
        right_ans = []
        def right_view(root,level) :
            if not root: return
            if level > len(right_ans) : right_ans.append(root.data)
            right_view(root.right,level+1)
            right_view(root.left,level-1)
        
        left_view(root,level = 1)
        right_view(root,level =1)
        
        return left_ans[::-1]+right_ans[1:]

失败的树:

               __________________23______________________
              /                                          \
          __17__                        _________________65__________________ 
         /      \                      /                                     \
      __9__      19            ______38_______                             __69__
     /     \    /  \          /               \                           /      \
    7      10  18  21       37       __________43__________              67      74
   / \       \    /  \     /        /                      \            /  \    /
  1   8      14  20  22  33       39                _______53_______   66  68  70
   \        /  \        /        /  \              /                \            \
    4      13  16   __29_      35   40           51                _62_          71 
   / \    /   /    /     \    /  \    \         /  \              /    \           \
  3   5  11  15  27      32  34  36   41      45   52          __58__  63          72 
 /     \   \    /  \    /               \    /  \             /      \   \           \
2       6  12  24  28  30               42  44   47          57      61  64          73
                 \       \                      /  \        /       /
                 26      31                    46  49      55      60 
                /                                 /  \    /  \    /
               25                                48  50  54  56  59

预期输出:

2 1 7 9 17 23 65 69 74 63 64

我的代码输出(错误):

2 1 7 9 17 23 65 69 74 72 73

您的算法假定首先访问最高节点,但情况并非总是如此。这是一个最小的例子:

           7
          / \
         1   11
          \ /
           2 (10)
          / \
         9   6
        /   /
       8   5 
          /
         4
        /
       3

注意从根开始spring的两个分支,向下交叉两层(11的左边child是10,1的右边child是2).由于您首先访问左子树,因此您将注册 3 从顶部可见。当您稍后遍历另一条路径时,它不会更新。

一个解决方案是保持找到节点的深度。如果稍后,在相同的垂直偏移量 (level) 处找到另一个候选节点,您可以比较这两个节点的深度并确定哪个节点在另一个节点之上。

第二个问题是挑战中提到解决方案应该 "Return 个从最左边的节点到最右边的节点。"。这个说法有点模棱两可,但似乎是指当两个节点高度相同,垂直偏移量相同时,应该优先遍历left-first找到的节点。但在 right_view 中你使用了相反的顺序:只需更改递归调用的顺序。

这是使用 depth 和固定递归 call-order 概念更新的函数:

def topView(self,root):
    left_ans = []
    left_depth = []
    def left_view(root,level,depth) :
        if not root:
            return 
        if level >= 0:
            if level >= len(left_ans): 
                left_ans.append(root.data)
                left_depth.append(depth)
            elif depth < left_depth[level]:
                left_ans[level] = root.data
                left_depth[level] = depth
        left_view(root.left,level+1,depth+1)
        left_view(root.right,level-1,depth+1)
    
    right_ans = []
    right_depth = []
    def right_view(root,level,depth):
        if not root:
            return
        if level >= 0:
            if level >= len(right_ans): 
                right_ans.append(root.data)
                right_depth.append(depth)
            elif depth < right_depth[level]:
                right_ans[level] = root.data
                right_depth[level] = depth
        right_view(root.left,level-1,depth+1)
        right_view(root.right,level+1,depth+1)
    
    left_view(root,0,0)
    right_view(root,0,0)

    return left_ans[::-1]+right_ans[1:]