提问人:user3371034 提问时间:3/2/2014 最后编辑:user3371034 更新时间:11/4/2023 访问量:10659
Java 中链表的深度复制构造函数
Deep Copy Constructor for Linked List in Java
问:
我有一个硬件分配,其中只有一小部分是制作一个复制构造函数,该构造函数会对您在其参数中输入的链表进行深度复制。
我理解这意味着,您输入的链表保持不变,并且新链表与“旧”链表隔离。我的代码给了我一个新列表,它与旧列表(您作为参数输入的列表)完全相同,这就是我想要的,但旧列表已更改。List
下面是构造函数:
public SortedLinkedSet(SortedLinkedSet<T> copy) {
if (copy == null) {
this.firstNode = null;
} else{
SortedLinkedSetNode firstNode1 = new SortedLinkedSetNode(copy.getFirstNode().value);
this.firstNode = firstNode1;
// so basically I am chaining elements from "copy" to firstNode1 and then making "this" = to firstNode1.
while (copy.firstNode.next !=null) {
firstNode1.add(copy.getFirstNode().next.value);
this.firstNode = firstNode1;
copy.firstNode = copy.firstNode.next;
// at the end of this loop I have a successful new linkedList with the same value, but "copy" has been changed
}
}
}
例如,如果我输入一个具有值的链表 - 使用这个构造函数,我得到一个带有值的新链表,但旧的链表只有 1。如果有人能帮助我解释为什么会出错,那就太好了。谢谢(1,2,3)
1,2,3
更新:正如 Ireeder 所指出的,通过我所做的测试,我几乎可以肯定问题出在陈述中: copy.firstNode = 复制.firstNode.next; 我删除了当前代码,并进行了以下测试:
SortedLinkedSetNode firstNode = new SortedLinkedSetNode(copy.getFirstNode().value);
this.firstNode=firstNode;
firstNode.add(copy.getFirstNode().next.value);
this.firstNode = firstNode;
firstNode.add(copy.getFirstNode().next.next.value);
this.firstNode = firstNode;
这工作得很好(但我事先知道我只用 3 个元素列表进行测试)。我将如何在不使用诸如以下语句的情况下使用 while 循环来做到这一点: copy.firstNode = 复制.firstNode.next; 我必须以某种方式沿着“复制”列表移动?
答:
如果不看到 的来源,很难说问题出在哪里,但你似乎正在用这句话修改你的原始内容:SortedLinkedSetNode
copy.firstNode= copy.firstNode.next;
这可能会将 firstNode 推进到原始 linkedset 的末尾,从而导致原始 linkedset 只有一个元素。此外,令人困惑的是,原件被称为“副本”。您可能希望重命名它,以便更好地理解您的代码。
创建深层副本时,不应修改要复制的结构。
在这种情况下,您可以只使用临时变量来存储对当前节点的引用,而无需修改原始数据结构。试试这个:
this.firstNode = firstNode1;
// so basically I am chaining elements from "copy" to firstNode1 and then making "this" = to firstNode1.
SortedLinkedSetNode currentNode = copy.firstNode;
while (currentNode.next !=null) {
firstNode1.add(currentNode.next.value);
this.firstNode = firstNode1;
currentNode = currentNode.next;
}
评论
首先要复制的原件,叫做,就像在复制这个吗?copy
您确实与正确的节点混淆了,并且代码不够简单。
简化事情的递归解决方案似乎是合适的:
public SortedLinkedSet(SortedLinkedSet<T> original) {
Objects.requireNotNull(original);
this.firstNode = copyNodes(orignal.firstNode);
}
private SortedLinkedSetNode copy(SortedLinkedSetNode originalNode) {
if (originalNode == null) {
return null;
}
SortedLinkedSetNode node = new SortedLinkedSetNode(originalNode.value);
node.next = copy(originalNode.next);
return node;
}
如果节点的值也需要深度复制,则可以在一个地方完成。
循环仍然很简单。一种方式:
private SortedLinkedSetNode copy(SortedLinkedSetNode originalNode) {
SortedLinkedSetNode firstNode = null;
SortedLinkedSetNode previousNode = null;
while (originalNode != null) {
SortedLinkedSetNode node = new SortedLinkedSetNode(originalNode.value);
if (firstNode == null) {
firstNode = node;
} else {
previousNode.next = node;
}
previousNode = node;
originalNode = originalNode.next;
}
return firstNode;
}
评论