在二叉树插入中,只有左树是右树。正确的树是错误的

时间:2019-08-08 18:17:19

标签: python recursion data-structures tree binary-tree

我有一个btree类和一个insert函数,可以将节点广泛地插入到树中。但是树没有在右边插入节点。

我正在创建根节点。 insert函数将左右节点正确地插入到根中。

然后,递归地,我尝试在左侧节点插入两个节点,在右侧节点插入两个节点。但是在此步骤中,所有节点仅添加到左侧。节点也将添加到“无”父级。

我知道,我在insert函数中的最后else语句中犯了一个错误。但是我尝试了很多组合,但是都导致了一些错误。

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

  def insert(self,val):
    if self.left is None:
      self.left = BinTree(val)
    elif self.right is None:
      self.right = BinTree(val)
    elif self.left:
      self.left.insert(val)
    else:
      self.right.insert(val)

root = BTree('A')
root.insert('B')
root.insert('C')
root.insert(None)
root.insert('D')
root.insert(None)
root.insert('E')
root.insert('F')
Expected:
                 A
              /     \
             B       C
            /\       /\
        None  D  None  E
             /
            F

Getting:
                 A
              /     \
             B       C
            / \
        None   D
         /  \
     None    E
       /
      F

3 个答案:

答案 0 :(得分:0)

您的树的构建完全符合您的代码建议。

$salt函数检查是否有一个空子节点,并设置是否找到了一个子节点-否则它将递归地移到左侧(无论其长度如何),而这正是您得到的树。

第二,您的输出内容不清楚-添加insert是什么意思?

为了实现完整树的构建,您需要保留元素数量。

然后,我们将能够使用以2计的除法来找到正确的路径(以叶子或右边),直到到达右边的叶子。将None添加到构造函数。将其用于伪代码进行插入:

self.cnt = 1

尝试查看树号以更好地理解它:

insert:
    cnt = self.cnt++ // Increase the count and get the new value
    while (cnt > 0) {
        path.push(cnt % 2 == 0 ? left : right) // If even, go left. Else go right.
        cnt = cnt / 2
    }
    path.reverse // We need to start from the last element we pushed
    current = head
    while (path not empty)
        current = current.path.pop
    current = val

答案 1 :(得分:0)

您的代码一旦找到不存在“无”的节点,便会向左遍历,就像depth-first search(DFS)。因此,该代码不会在右侧进一步查看是否仍然需要填补一些空缺,但无论如何都要去掉。这会导致偏向您的树的左侧。

相反,您应该使用breadth-first search(BFS)搜索树中的下一个空位,因此以 breadth 的第一顺序。为此,您可以使用一个单独的方法来执行此BFS并返回空缺的位置(通过提供其父节点以及新的子节点应位于哪一侧)。

这是新方法的外观:

def next_free(self):
    queue = [self]
    while len(queue):
        node = queue.pop(0) # Here you get the nodes in BFS order
        if node.val is None: # Cannot have children
            continue
        for side, child in enumerate((node.left, node.right)):
            if child is None: # Found the first vacancy in BFS order!
                return node, side
            queue.append(child)

现在insert方法变得微不足道了:

def insert(self,val):
    node, side = self.next_free()
    if side == 0:
        node.left = Node(val)
    else:
        node.right = Node(val)

您可以看到它在repl.it上运行。

答案 2 :(得分:-1)

使用保存的当前字段递归实际上无法获得所需的结果。每个节点仅“知道”其当前状态,因此树的右侧将永远保留在深度1。

想到的一种解决方案是添加right childrenleft children数量字段。这将有助于跟踪余额。看起来像这样:

 class Node(object):
    def __init__(self, val):
        self.val = val
        self.left = None
        self.right = None
        self.right_count = 0
        self.left_count = 0
        self.even_depth = True
        self.needed_to_even = 1

    def insert(self, val):
        if self.left is None:
            self.left = Node(val)
            self.left_count += 1
        elif self.right is None:
            self.right = Node(val)
            self.right_count += 1
        elif self.left_count > self.right_count + self.needed_to_even or not self.even_depth:
            self.even_depth = False
            if self.left_count == self.right_count:
                self.needed_to_even *= 2
                self.even_depth = True
            self.right.insert(val)
            self.right_count += 1
        else:
            self.left.insert(val)
            self.left_count += 1