如何在python中替换子树

时间:2015-12-08 21:34:26

标签: python tree

我的树数据结构如下:

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

然后树正确更新。我怎样才能使用上面的方法实现它?

1 个答案:

答案 0 :(得分:1)

作业node = newNode没有做你想做的事。它并不会将您知道的对象node替换为newNode。它只是重新绑定局部变量名node以指向与其他本地名称newNode相同的对象。对第一个节点的其他引用(例如在其父级children列表中)将保持不变。

实际上做你想做的事需要更精细。最好的方法通常是根本不替换节点,而是替换它的内容。也就是说,将node.datanode.children设置为等于newNode.datanewNode.children并保留node。如果有其他对nodenewNode的引用,并且您希望它们在替换后正常工作,则无法正常工作。

另一种方法是在您正在寻找的节点的父节点中进行替换。这不会在你的树顶工作,所以你需要特殊的逻辑来处理这种情况。

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