请考虑以下代码
public class Pair implements Cloneable, Comparable<Para> {
...
public Pair(String key, double value) throws Exception {
if (value <= 0) throw new IllegalArgumentException();
this.key = key;
this.value = value;
}
...
@Override
public Pair clone() throws CloneNotSupportedException {
return (Pair) super.clone();
}
}
和
public class BSTtree implements Dictionary, Cloneable {
...
private class Node implements Cloneable, Comparable<Node> {
Para elem;
Node left = null;
Node right = null;
Node parent = null;
Node () {
this.elem = null;
}
Node (Pair elem) {
this.elem = elem;
}
...
@Override
public Node clone() throws CloneNotSupportedException {
Node cloned = new Node();
cloned.elem = elem.clone();
if (left != null) cloned.left = left.clone();
if (right != null) cloned.right = right.clone();
return cloned;
}
}
...
@Override
public BSTtree clone() throws CloneNotSupportedException {
BSTtree cloned = new BSTtree();
cloned.root = root.clone();
return cloned;
}
}
我正在尝试使用Cloneable
接口实现自己的BST树。我遇到问题的地方是
BSTtree alfa = new BSTtree();
...
BSTtree beta = alfa.clone();
我假设没有正确设置对树alfa
和beta
的引用。我为什么这么认为?请看下面的
alfa.printTree(); //(VOID 1,00), (a 1,00), (b 2,00), (c 3,00), (e 5,00)
beta.printTree(); //(VOID 1,00), (a 1,00), (b 2,00), (c 3,00), (e 5,00)
beta.remove("a");
alfa.printTree(); //(VOID 1,00), (b 2,00), (c 3,00), (e 5,00)
beta.printTree(); //(VOID 1,00), (a 1,00), (b 2,00), (c 3,00), (e 5,00)
alfa.remove("e");
alfa.printTree(); //(VOID 1,00), (b 2,00), (c 3,00), (e 5,00)
beta.printTree(); //(VOID 1,00), (a 1,00), (b 2,00), (c 3,00), (e 5,00)
因此,您可以在克隆后看到从beta
中移除的任何内容实际上已从alfa
移除,并且从alfa
移除根本不会删除。当然,在调用clone()
之前alfa
上的每个操作都正常工作。
这是为了学习,主要任务是实现一个有效的clone()
方法,因此我不想使用任何其他方法来执行深层复制。
请告知我的错误,因为自我调试还没有帮助。
答案 0 :(得分:2)
父更新似乎缺失 - 不确定这是否是唯一的问题......
@Override
public Node clone() throws CloneNotSupportedException {
Node cloned = new Node();
cloned.elem = elem.clone();
if (left != null) {
cloned.left = left.clone();
cloned.left.parent = cloned;
}
if (right != null) {
cloned.right = right.clone();
cloned.right.parent = cloned;
}
return cloned;
}
P.S。我认为另一个问题是Node是一个非静态内部类。所以它总是有一个隐含的指向它在中创建的树的指针。如果在Node.clone中调用新的Node(),则它位于原始树的范围内,因此它仍将指向原始树,但它必须是新树的内部类。在内部类声明中添加static将突出显示问题。
您可能希望将其转换为静态内部类并添加一个指向树的显式指针(如果您需要它 - 一些访问root的Node方法看起来应该是BSTtree方法)。