当前位置: 首页 > 知识库问答 >
问题:

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

赵越
2023-03-14

我有一个btree类和一个insert函数,可以在树的宽度方向上插入节点。但树没有在右侧插入节点。

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

然后递归地,我尝试在左侧节点插入两个节点,在右侧节点插入两个节点。但在这一步中,所有节点仅添加到左侧。节点也会添加到无父节点。

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

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个答案

鞠晋
2023-03-14

你不能用你保存的当前字段通过递归真正得到你想要的结果。每个节点只“知道”它的当前状态,这就是为什么你树的右侧将永远保持在深度1。

我想到的一个解决方案是添加一个右孩子左孩子金额字段。这将有助于跟踪余额。它看起来像这样:

 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
董高畅
2023-03-14

您的树完全按照代码建议进行构建。

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

其次,您的输出不清楚-添加None是什么意思?

为了实现完整树的构建,你需要计算你的元素

然后我们将能够使用计数除以2来找到正确的路径(取叶子或右边),直到到达正确的叶子。添加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
           /   \
          2     3
         / \   /  \
        5   6 7    8
朱鸿畅
2023-03-14

一旦你的代码在那里找到一个不是无的节点,它就会向左遍历,这就像深度优先搜索(DFS)。所以代码不会再看右边是否还有一些空缺需要填补,而是向左移动。这会导致你的树偏向左边。

相反,您应该使用广度优先搜索(BFS)来搜索树中的下一个空缺,因此以广度优先的顺序进行搜索。为此,您可以使用一个单独的方法来执行此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)

现在,插入方法变得微不足道:

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

你可以看到它在repl上运行。信息技术

 类似资料:
  • 二叉搜索树(BST)和二叉树(BT)中的插入有什么区别?我知道,在BST中,您将新节点的值与根进行比较,如果较小,则添加到其左侧,如果较大,则将其添加到根的右侧。BT的程序是否相同?如果没有,插入和移除的步骤是什么?

  • 我有一个很严重的问题,就是在一棵树中重复搜索子树。 我试过了,但是。。。 似乎没有正确的形式。containsTree函数在找到与另一个节点不同的节点时停止搜索。 下面是两棵树的例子。 在这种情况下,当函数比较右边的子树和左边的子树时,当find等于父节点但它有不同的子节点时,它会停止搜索。我需要函数不要停止搜索,而是抛出这一点,搜索所有其他子节点及其子树。

  • QSTN:当它是叶节点时,为什么需要初始化ls=0或rs=0。考虑链接中给出的树,如果我们到达节点4,如果(node==NULL isLeaf(node))返回1;上面的代码将1(true)返回到调用它的函数,即节点10,类似地,右侧将true返回到节点10,因此我们现在可以进入下面的循环,因为如果(isSumTree(node->left)&&isSumTree(node->left)&&isS

  • 我写了一个函数,如果给定的二叉树是二叉搜索树,则返回true,否则返回false。 我的功能对吗?

  • 我正试图解决这个问题,但我遇到了一些麻烦: 在二进制搜索树(BST)中: 节点左子树中每个节点的数据值小于该节点的数据值。 节点右侧子树中每个节点的数据值大于该节点的数据值。 如您所见,节点(4)位于节点(3)的左侧子树中,尽管4大于3,因此方法应该返回。但是,我的代码返回。 我怎么能控制这个案子?如何检查左/右子树中的所有值都低于/大于根(不仅是直接子树)?

  • 主要内容:二叉树的性质,满二叉树,完全二叉树,总结通过《 树的存储结构》一节的学习,我们了解了一些树存储结构的基本知识。本节将给大家介绍一类具体的树结构—— 二叉树。 简单地理解,满足以下两个条件的树就是二叉树: 本身是有序树; 树中包含的各个节点的度不能超过 2,即只能是 0、1 或者 2; 例如,图 1a) 就是一棵二叉树,而图 1b) 则不是。 图 1 二叉树示意图 二叉树的性质 经过前人的总结,二叉树具有以下几个性质: 二叉树中,第 i