我有一个用ruby实现的树数据结构。我用它代表一个解析树。
正如您所料,它有许多节点对象,每个节点对象包含有用的值以及对其子节点的引用数组。
我编写了一个遍历树的方法,这个方法非常简单,其工作原理如下:
def depth_first_traversal(node, &block)
if(node.has_children?)
depth_first_traversal(node.children[0], &block)
yield node
depth_first_traversal(node.children[1], &block)
else
yield node
end
end
问题在于,对于每个树,我只显式保存对根节点的引用。到目前为止,我一直在使用我的递归遍历来访问所有其他节点。
现在我需要更改树中节点的值,我不知道该怎么做。
我怎么能修改这个遍历,以便我可以修改树中的每个元素,而不是只是将对它们的引用传递给&block?
---编辑:---
对于缺乏细节的道歉,我试图使我的问题广泛而有用。
树中节点的“值”是节点对象的每个实例中的几个实例变量。让我们称他们为@value
和@type
。它们有getter和setter方法。
树是二叉树 - 但可能会在以后更改。我也不认为这是我正在努力解决的问题的方面:
我的树显式创建了节点@root
。树中的所有其他节点都是在循环中创建的。因此,典型的节点是可访问的,例如作为“根的孩子的孩子”而不是其他方式。
换句话说,搜索指针结构是我访问节点的唯一方法。 如果ruby仅通过值传递,则产生的任何值(如上述方法中)将是此对象的副本,而不是对象本身。
所以我对如何修改任何树中的值感到困惑,而不仅仅是这个。
答案 0 :(得分:0)
如果我理解正确,你可能会做这样的事情:
def df_tree_map(node, &block)
if(node.has_children?)
df_tree_map(node.children[0], &block)
node = yield node
df_tree_map(node.children[1], &block)
else
node = yield node
end
end
显然这会对树结构产生影响,但这可能是一个好处。这里的关键点是你需要返回一个节点而不是任何旧节点。例如,返回一个字符串不会像Array#map那样工作,因为一个节点本身就有子节点。
另一种解决方案是允许map函数修改节点的内容而不是结构。我在这里采取一点自由,因为你没有发布实例变量节点也有访问权限,但它应该有足够的意义:
def df_tree_map(node, &block)
if(node.has_children?)
df_tree_map(node.children[0], &block)
node.contents = yield node.contents
df_tree_map(node.children[1], &block)
else
node.contents = yield node.contents
end
end
这里,我没有将节点本身传递给块,而是将内容传递给块。这样,地图就不能改变树结构。看起来它可能与Array#map函数更加一致,但它可能无法满足您的需求。