问题描述
所以我正在逐级遍历具有属性 id 和 name 的节点的 n 元树,我想更改每个节点的名称并创建另一个具有更改节点的类似 n 元树(根节点具有 { {1}} 为 A
)
id
但这不会返回正确的新树的根节点。事实上,这仅返回根节点及其直接子节点,但没有进一步的深度。任何人都可以帮助正确地做到这一点
解决方法
您的尝试不是跟踪您正在制作的副本,因此您不是在构建一棵树,只是一堆单节点副本及其子项:
queue.add(node);
Node copiedNode = null;
while(!queue.isEmpty()){
Node next = queue.remove();
// A new copy (not being referenced by anything)
copiedNode = new Node(next.id,next.name);
for (Node child : next.children) {
// A new copy (referenced by only the aforementioned copy
Node copiedChildNode = new Node(child.id,child.name);
copiedNode.children.add(copiedChildNode);
// If the original was "A",store a reference to the copy.
if (next.id == "A") rootOut = copiedNode;
// The original is queued,not the copy
queue.add(child);
}
}
// Return only the shallow copy
return rootOut ;
您需要在副本中构建一个结构,跟踪引用:
Queue<Node> queue = new LinkedList<>();
queue.add(node);
Node rootOut = new Node(node.id,node.name);
// For tracking copies
Map<String,Node> copiedNodesById = new HashMap<>();
copiedNodesById.put(rootOut.id,rootOut);
while(!queue.isEmpty()){
Node currentOriginal = queue.remove();
// Get an existing copy rather than making a new one.
Node currentCopy = copiedNodesById.get(currentOriginal.id);
for (Node childOriginal : currentOriginal.children) {
Node copiedChildNode = new Node(childOriginal.id,childOriginal.name);
currentCopy.children.add(copiedChildNode);
// Track the copy that was just made.
copiedNodesById.put(copiedChildNode.id,copiedChildNode);
if (next.id == "A") rootOut = currentCopy;
queue.add(childOriginal);
}
}
return rootOut ;
我冒昧地重命名了一些变量,以便更清楚地说明什么是原始版本和副本。
复制的节点也可能在另一个队列中被跟踪。或者队列可以跟踪(原始、复制)元组。
至于根据“A”的位置重构副本,我将把它留给你,因为我不清楚它应该如何运作。