不确定为什么节点仍然没有深度复制?头部和大小都很深的复制完美。
似乎NewNode-> Data和NewNode-> Next不是深度复制。不确定NewNode是否仍然指向That-> Data和That-> Next。
创建节点时是否需要传递实际值?
提前感谢您的回复。非常感谢。
传入的列表(SLList& that)。
Node是结构。节点不使用尾部。在我的案例中只有下一个和大小。
Node* That = that.Head;
//If not null then deep copy.
if (That != nullptr)
{
Head = that.Head;
Size = that.Size;
//Interate through the list until the end nullptr
while (That != nullptr)
{
Node* NewNode = new Node;
NewNode->Data = That->Data;
NewNode->Next = That->Next;
That = That->Next;
}
}
//Set the head to null if list passed in is empty.
else if (That == nullptr)
{
Head = nullptr;
Size = 0;
}
答案 0 :(得分:-1)
以下是更正后的代码。
Node* That = that.Head;
List new_list;
//If not null then deep copy.
if (That != nullptr)
{
new_list.Head=new Node;
new_list.Size = that.Size;
Node * head = new_list.Head;
//Interate through the list until the end nullptr
do{
head->Data = That->Data;
That = That->Next;
if(That!=nullptr){
auto tmp = new Node;
head->Next = tmp;
head = tmp;
}
}while(That!=nullptr);
//Set the head to null if list passed in is empty.
else if (That == nullptr)
{
new_list.Head = nullptr;
new_list.Size = 0;
}
return new_list;
答案 1 :(得分:-1)
问题1:
Head = that.Head;
Whups!两个名单指向同一个头。这不会很好。事实上,它彻底击败了链表的深层副本。
解决方案:
不要这样做。
问题2:
while (That != nullptr)
{
Node* NewNode = new Node;
NewNode->Data = That->Data;
NewNode->Next = That->Next;
That = That->Next;
}
NewNode
永远不会保存在循环外的任何地方。这使得这个循环成为一个丢失所有副本的内存泄漏生成器。
解决方案:
按照您目前的方式复制节点,但将第一个复制的节点存储在Head
。
问题3:
NewNode->Next = That->Next;
副本指向要复制的列表上的节点。
解决方案:
NewNode->Next
需要指向其列表中的下一个节点。不幸的是,这个节点还不存在。因此,您必须先创建新节点或使用递归。
答案 2 :(得分:-1)
关于代码中原始“新”调用的样式以及稍后要清理的内容,我要说的很多,我看到的明显错误是你忘记“链接”到你的“NewNode”而是正在链接到你正在复制的列表中的那个>下一个。
由于您的列表是单链接的,您需要保持指向当前“尾部”的指针,然后在创建新节点时,放置(使用您的样式)
Tail->Next = NewNode;
NewNode->Data = That->Data;
Tail = NewNode;
您实际在做的是创建一个克隆数据的节点,但您的链接列表没有使用新节点,但仍使用旧节点。
由于这是C ++,你有一个构造函数,NewNode应该自动创建nullptr作为其“Next”值,所以如果我们不进一步循环,我们可以假设已经设置。
实际上,我们也可以将所需的数据传递给构造函数,因此:
template< typename DataType >
class SLNode
{
public:
DataType Data;
SLNode< DataType > * Next;
SLNode() : Next( nullptr )
{
}
~SLNode(); // exercise for you to implement
explicit SLNode( const DataType& data )
: Data( data ), Next( nullptr )
{
}
};
我已将所有内容公之于众,但您可能希望将数据成员设为私有,并使用getter和setter。
无论如何,现在你可以在循环中执行以下操作....
while( That )
{
Tail->Next = new SLNode< DataType >( That->Data );
Tail = Tail->Next;
That = That->Next;
}
新列表中的“头部”也不正确,因为它指向旧列表中的节点。不过,我们现在知道如何创建
Head = new SLNode< DataType >( that->Data );
Tail = Head;
我们需要保持头部和尾部,因为尾巴会随着我们的进攻而移动,头部将保持不变并且是我们列表的头部。