我有一个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
答案 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 children
和left 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