我的树数据结构如下:
class Node(object):
def __init__(self, data):
self.data = data
self.children = []
def add_child(self, obj):
self.children.append(obj)
然后我创建了一个方法来完成它。
def replace(node, newNode):
if node.data == 1:
node = newNode
return
else:
for i in xrange(0, len(node.children)):
replace(node.children[i], newNode)
这个方法就像这样调用:
replace(mytree,newNode)
由于它是递归调用,我认为对象被破坏并且分配不会发生。
我手动尝试了:
mytree.children[0].children[0] = newNode
然后树正确更新。我怎样才能使用上面的方法实现它?
答案 0 :(得分:1)
作业node = newNode
没有做你想做的事。它并不会将您知道的对象node
替换为newNode
。它只是重新绑定局部变量名node
以指向与其他本地名称newNode
相同的对象。对第一个节点的其他引用(例如在其父级children
列表中)将保持不变。
实际上做你想做的事需要更精细。最好的方法通常是根本不替换节点,而是替换它的内容。也就是说,将node.data
和node.children
设置为等于newNode.data
和newNode.children
并保留node
。如果有其他对node
或newNode
的引用,并且您希望它们在替换后正常工作,则无法正常工作。
另一种方法是在您正在寻找的节点的父节点中进行替换。这不会在你的树顶工作,所以你需要特殊的逻辑来处理这种情况。
def replace(node, newNode):
if node.value == 1:
raise ValueError("can't replace the current node this way")
for index, child in enumerate(node.children):
if child.data == 1:
node.children[index] = newNode
return True
if replace(child, newNode):
return True
return False
我还添加了一些额外的逻辑来在找到适当的节点时停止树的递归处理。如果已进行替换,则该函数将返回True
;如果未找到正确的False
值,则该函数将返回data
。