【问题标题】:Level-filled binary tree水平填充二叉树
【发布时间】:2019-06-28 00:43:02
【问题描述】:

为了更好地理解递归函数,我正在尝试为二叉树创建一个 Python 脚本,用于插入值,在进入下一个之前完全填充级别。

这是我的树节点实现:

class Node:
    def __init__(self, value):
        self.value = value
        self.right_child = None
        self.left_child = None
        self.parent = None

class Tree:
    def __init__(self):
        self.root = None

我现在遇到的问题是设置满足该标准的条件。

一个例子:这里我按顺序添加以下数字:12、5、18、2、9、15、19、13、17。因此,将东西放入下一个级别的唯一条件是父级已满。

  _12_______
 /          \
 5       __18_
/ \     /     \
2 9    15_   19
/   \
13  17

这是我目前所拥有的:

def insert(self,value):
    if(self.root==None):
            self.root=Node(value)
    else:
            self._insert(value,self.root)

def _insert(self, value, curNode):
        if(curNode.left_child==None):
                curNode.left_child=Node(value)
                curNode.left_child.parent = curNode

        elif(curNode.right_child==None):
                curNode.right_child=Node(value)    
                curNode.right_child.parent = curNode    

        else:
                self._insert(value,curNode.left_child)

给出:

          _12_
         /    \
       __5   18
      /   \
    __2_  9
   /    \
  15_  19
 /   \
13  17

因此忽略所有正确的孩子。问题当然是我代码的最后一个else。我怎样才能让这个考虑节点的左右子节点?

【问题讨论】:

  • 您可能应该提供更多代码来帮助希望帮助您的人,以便他们可以运行您的代码的最小示例。您的树类对初学者很有帮助。
  • 当然,它是基本的树类节点类实现。我现在正在把它写在帖子里。谢谢!
  • 你说的是二叉树,而不是二叉 search 树,看起来你实际上想要做的是在树的形式。代替您当前的方法(在正确的位置插入),一种更有用的方法可能是“在某处插入叶子,然后将树旋转直到平衡”。另请查看self-balancing binary search trees

标签: python binary-tree


【解决方案1】:

你实际上不需要一个带有左右指针的节点结构。只需将整个树存储在一个数组中,以便索引N 处的节点的子节点位于2*N+12*N+2

def print_tree(items, pos, level):
    if pos >= len(items):
        return
    print('.' * level, items[pos])
    print_tree(items, pos * 2 + 1, level + 1)
    print_tree(items, pos * 2 + 2, level + 1)


print_tree([12, 5, 18, 2, 9 , 15, 19, 13, 17], 0, 0)

打印

 12
. 5
.. 2
... 13
... 17
.. 9
. 18
.. 15
.. 19

这就是你想要的。

这称为binary heap

如果您正在寻找搜索树(保持值顺序的),并希望保持平衡,请查看https://en.wikipedia.org/wiki/Self-balancing_binary_search_tree

【讨论】:

    【解决方案2】:

    georg's answer 是表示这一点的明智方式。但是,如果您对如何使用树结构来获得相同的结果感兴趣,您可以将问题分成两部分:首先找到最浅的不完整节点,然后添加一个新节点。这是一种方法:

    class Node:
        def __init__(self, value):
            self.value = value
            self.right_child = None
            self.left_child = None
            self.parent = None
    
    class Tree:
        def __init__(self):
            self.root = None
    
        def insert(self, value):
            if self.root is None:
                self.root = Node(value)
            else:
                # Find shallowest incomplete node (ignore returned depth)
                node, _ = Tree._next_insertion_node(self.root)
                # Add new node to it
                if node.left_child is None:
                    node.left_child = Node(value)
                else:
                    node.right_child = Node(value)
    
        @staticmethod
        def _next_insertion_node(node, level=0):
            # Returns shallowest incomplete node and its depth
            if node.left_child is None or node.right_child is None:
                return node, level
            node_left, level_left = Tree._next_insertion_node(node.left_child, level + 1)
            node_right, level_right = Tree._next_insertion_node(node.right_child, level + 1)
            if level_left <= level_right:
                return node_left, level_left
            else:
                return node_right, level_right
    
        def print(self):
            Tree._print_node(self.root)
    
        @staticmethod
        def _print_node(node, level=0):
            if node is None: return
            print(' ' * (level * 2), '*', node.value)
            Tree._print_node(node.left_child, level + 1)
            Tree._print_node(node.right_child, level + 1)
    
    numbers = [12, 5, 18, 2, 9 , 15, 19, 13, 17]
    tree = Tree()
    for number in numbers:
        tree.insert(number)
    tree.print()
    # * 12
    #   * 5
    #     * 2
    #       * 13
    #       * 17
    #     * 9
    #   * 18
    #     * 15
    #     * 19
    

    【讨论】:

      【解决方案3】:

      不确定这是不是最好的方法,但我尝试编写类似于您尝试的方法的内容。我们不是立即转到左侧节点,而是记录两个节点,然后按顺序遍历它们,以便我们看到它们。所以首先是根,然后是 root.left、root.right、root.left.left、root.left.right、root.right.left ...等

      class Node:
          def __init__(self, value):
              self.value = value
              self.right_child = None
              self.left_child = None
              self.parent = None
      
      class Tree:
          def __init__(self):
              self.root = None
      
          # record nodes that need processing.
          nodes_to_process = []
      
          def insert(self,value):
              if(self.root==None):
                  self.root=Node(value)
              else:
                  # add the node to be processed
                  self.nodes_to_process.append(self.root)
                  self._insert(value)
      
          def _insert(self,value):
              # the current node is the next node in the list.
              curNode = self.nodes_to_process[0]
      
              if(curNode.left_child==None):
                  curNode.left_child=Node(value)
                  curNode.left_child.parent = curNode
                  # reset the list, since we've inserted.
                  self.nodes_to_process = []
      
              elif(curNode.right_child==None):
                  curNode.right_child=Node(value)    
                  curNode.right_child.parent = curNode   
                  # reset the list, since we've inserted.
                  self.nodes_to_process = []
      
              else:
                  # insert the two child nodes.
                  self.nodes_to_process.append(curNode.left_child)
                  self.nodes_to_process.append(curNode.right_child)
                  # Remove the node we've just examined.
                  self.nodes_to_process.pop(0)
                  self._insert(value)
      
      

      这是一个快速测试。

      tree = Tree()        
      
      for number in [12, 5, 18, 2, 9 , 15, 19, 13, 17]:
          tree.insert(number)
      
      print(tree.root.value) # 12
      print(tree.root.left_child.value) #5
      print(tree.root.left_child.left_child.value) # 2
      print(tree.root.left_child.left_child.left_child.value) # 13
      print(tree.root.left_child.left_child.right_child.value) # 17
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-09-02
        相关资源
        最近更新 更多