递归打印树的节点时出错
Error in recursively printing nodes of a tree
示意图:有一个节点 class 用于支持树结构。这个 class 的每个实例都将有一个字典,用于它们的所有子项、一个父项和要存储的数据。
make_children 获取调用对象并将参数添加为子对象。 childs parent 设置为 self,因为当前调用对象是父节点。然后将此子项作为子项添加到当前对象字典中。
print_tree 获取当前调用对象并打印 value 属性,同时递归调用自身并在到达叶节点后停止。
我正在尝试玩弄并学习递归和树。我正在尝试获得以下输出。
[12, 7, 8, 15]
[12, 7]
[8, 15]
[12]
[7]
[8]
[15]
而是得到:
[12, 7, 8, 15]
[12, 7]
[8, 15]
我做错了什么?我怀疑问题在于 print_tree、build_file_tree 中的回避或 build_file_tree 中的 return 语句。我尝试使用 print 语句打印左半边和右半边,它们似乎工作正常,这让我更倾向于 print_tree.
class Node:
def __init__(self, value):
self.value = value
self.children = []
self.parent = None
def make_children(self, child):
child.parent = self
self.children.append(child)
def print_tree(self): #ISSUE?
print(self.value)
if len(self.children) > 0: # leaf node case
for child in self.children:
child.print_tree()
def build_file_tree(list1):
#list1 = [12, 7, 8, 15]
#root = Node(56)
root = Node(list1)
#child1 = Node(12)
#child2 = Node(24)
temp = len(list1) // 2
left_half = list1[:temp]
right_half = list1[temp:]
if len(left_half) > 1: # ISSUE HERE?
build_file_tree(left_half)
if len(right_half) > 1: # ISSUE HERE?
build_file_tree(right_half)
child1 = Node(left_half)
child2 = Node(right_half)
root.make_children(child1)
root.make_children(child2)
return root #ISSUE?
if __name__ == '__main__':
list1 = [12, 7, 8, 15]
file = build_file_tree(list1)
file.print_tree()
如果列表的长度为 1,则不会创建 Child。但是,如果您想要描述的行为,则应该这样做。
如果 list1
只包含一个或更少的元素,您还需要停止递归。
而且您没有捕捉到返回的 root
元素。
您的代码可能如下所示:
class Node:
def __init__(self, value):
self.value = value
self.children = []
self.parent = None
def make_children(self, child):
child.parent = self
self.children.append(child)
def print_tree(self): #ISSUE?
print(self.value)
if len(self.children) > 0: # leaf node case
for child in self.children:
child.print_tree()
def build_file_tree(list1):
#list1 = [12, 7, 8, 15]
#root = Node(56)
root = Node(list1)
#child1 = Node(12)
#child2 = Node(24)
if len(list1) > 1:
temp = len(list1) // 2
left_half = list1[:temp]
right_half = list1[temp:]
child1 = build_file_tree(left_half)
root.make_children(child1)
child2 = build_file_tree(right_half)
root.make_children(child2)
return root
if __name__ == '__main__':
list1 = [12, 7, 8, 15]
file = build_file_tree(list1)
file.print_tree()
调试步骤:
def __init__(self, value):
print(f"Creating node for {value}")
这将向您展示您实际上创建了两棵不同的树。这是由于在 left_half
上调用 Node
(应称为 Tree
)为 Node(left_half)
,然后在 build_file_tree(left_half)
中调用为 Node(list1)
。
这意味着每个子树只有 2 层的高度,之后您将使用没有父关系集的新实例调用 make_children。
我的解决方案是按如下方式更改 build_file_tree
函数:
def build_tree(value_list):
root = Tree(value_list)
if len(value_list) == 1:
return root
mid_point = len(value_list) // 2
left_half = value_list[:mid_point]
right_half = value_list[mid_point:]
child1 = build_tree(left_half)
root.make_child(child1)
child2 = build_tree(right_half)
root.make_child(child2)
return root
我做了一些轻微的重构,但你应该能理解这个想法
示意图:有一个节点 class 用于支持树结构。这个 class 的每个实例都将有一个字典,用于它们的所有子项、一个父项和要存储的数据。
make_children 获取调用对象并将参数添加为子对象。 childs parent 设置为 self,因为当前调用对象是父节点。然后将此子项作为子项添加到当前对象字典中。
print_tree 获取当前调用对象并打印 value 属性,同时递归调用自身并在到达叶节点后停止。
我正在尝试玩弄并学习递归和树。我正在尝试获得以下输出。
[12, 7, 8, 15]
[12, 7]
[8, 15]
[12]
[7]
[8]
[15]
而是得到:
[12, 7, 8, 15]
[12, 7]
[8, 15]
我做错了什么?我怀疑问题在于 print_tree、build_file_tree 中的回避或 build_file_tree 中的 return 语句。我尝试使用 print 语句打印左半边和右半边,它们似乎工作正常,这让我更倾向于 print_tree.
class Node:
def __init__(self, value):
self.value = value
self.children = []
self.parent = None
def make_children(self, child):
child.parent = self
self.children.append(child)
def print_tree(self): #ISSUE?
print(self.value)
if len(self.children) > 0: # leaf node case
for child in self.children:
child.print_tree()
def build_file_tree(list1):
#list1 = [12, 7, 8, 15]
#root = Node(56)
root = Node(list1)
#child1 = Node(12)
#child2 = Node(24)
temp = len(list1) // 2
left_half = list1[:temp]
right_half = list1[temp:]
if len(left_half) > 1: # ISSUE HERE?
build_file_tree(left_half)
if len(right_half) > 1: # ISSUE HERE?
build_file_tree(right_half)
child1 = Node(left_half)
child2 = Node(right_half)
root.make_children(child1)
root.make_children(child2)
return root #ISSUE?
if __name__ == '__main__':
list1 = [12, 7, 8, 15]
file = build_file_tree(list1)
file.print_tree()
如果列表的长度为 1,则不会创建 Child。但是,如果您想要描述的行为,则应该这样做。
如果 list1
只包含一个或更少的元素,您还需要停止递归。
而且您没有捕捉到返回的 root
元素。
您的代码可能如下所示:
class Node:
def __init__(self, value):
self.value = value
self.children = []
self.parent = None
def make_children(self, child):
child.parent = self
self.children.append(child)
def print_tree(self): #ISSUE?
print(self.value)
if len(self.children) > 0: # leaf node case
for child in self.children:
child.print_tree()
def build_file_tree(list1):
#list1 = [12, 7, 8, 15]
#root = Node(56)
root = Node(list1)
#child1 = Node(12)
#child2 = Node(24)
if len(list1) > 1:
temp = len(list1) // 2
left_half = list1[:temp]
right_half = list1[temp:]
child1 = build_file_tree(left_half)
root.make_children(child1)
child2 = build_file_tree(right_half)
root.make_children(child2)
return root
if __name__ == '__main__':
list1 = [12, 7, 8, 15]
file = build_file_tree(list1)
file.print_tree()
调试步骤:
def __init__(self, value):
print(f"Creating node for {value}")
这将向您展示您实际上创建了两棵不同的树。这是由于在 left_half
上调用 Node
(应称为 Tree
)为 Node(left_half)
,然后在 build_file_tree(left_half)
中调用为 Node(list1)
。
这意味着每个子树只有 2 层的高度,之后您将使用没有父关系集的新实例调用 make_children。
我的解决方案是按如下方式更改 build_file_tree
函数:
def build_tree(value_list):
root = Tree(value_list)
if len(value_list) == 1:
return root
mid_point = len(value_list) // 2
left_half = value_list[:mid_point]
right_half = value_list[mid_point:]
child1 = build_tree(left_half)
root.make_child(child1)
child2 = build_tree(right_half)
root.make_child(child2)
return root
我做了一些轻微的重构,但你应该能理解这个想法