C++ 编码一个函数以复制C++;
我需要实现一个名为copyList的辅助函数,它有一个参数,一个指向ListNode的指针。此函数需要返回指向原始链表副本的第一个节点的指针。换句话说,我需要在C++中编写一个函数,该函数使用链表的头节点并复制整个链表,返回指向新的头节点的指针。我需要帮助实现这个功能,这就是我现在拥有的C++ 编码一个函数以复制C++;,c++,linked-list,C++,Linked List,我需要实现一个名为copyList的辅助函数,它有一个参数,一个指向ListNode的指针。此函数需要返回指向原始链表副本的第一个节点的指针。换句话说,我需要在C++中编写一个函数,该函数使用链表的头节点并复制整个链表,返回指向新的头节点的指针。我需要帮助实现这个功能,这就是我现在拥有的 Listnode *SortedList::copyList(Listnode *L) { Listnode *current = L; //holds the current node
Listnode *SortedList::copyList(Listnode *L) {
Listnode *current = L; //holds the current node
Listnode *copy = new Listnode;
copy->next = NULL;
//traverses the list
while (current != NULL) {
*(copy->student) = *(current->student);
*(copy->next) = *(current->next);
copy = copy->next;
current = current->next;
}
return copy;
}
此外,这是我正在使用的Listnode结构:
struct Listnode {
Student *student;
Listnode *next;
};
注意:这个函数遇到的另一个因素是返回一个指向局部变量的指针
copy->next=current->next
这是错误的。你应该这样做
Create the first node copy here
copy->student = current->student;
copy->next = NULL;
while(current->next!=NULL)
{
Create new node TEMP here
copy->next = TEMP;
TEMP->student = current->student;
TEMP->next = NULL;
copy = TEMP;
}
由于需要链接列表的副本,因此在遍历原始列表时需要在循环中创建一个新节点
Listnode *startCopyNode = copy;
while (current != NULL) {
*(copy->student) = *(current->student);
copy->next = new Listnode;
copy = copy->next;
current = current->next;
}
copy->next = NULL;
return startCopyNode;
请记住删除链接列表的节点。这是一个很好的问题,因为你自己已经完成了大部分工作,远远好于大多数“请为我做作业”问题
几点
首先,如果传入一个空列表,会发生什么?您可能希望提前了解这一点,然后将一个空列表返回给调用方
第二,您只分配复制列表中的第一个节点,您需要为原始列表中的每个节点分配一个节点
类似(伪代码(但类似C++)的作业,抱歉):
而且,虽然您不应该返回指向本地堆栈变量的指针是正确的,但这不是您要做的。您返回的变量指向堆分配的内存,该内存将在函数退出后继续存在。@pat,我猜您将遇到seg_错误,因为您只创建了一次内存。您需要为每个节点创建内存(基本上称为“新建”)。找出需要使用“new”关键字为所有节点创建内存的位置
完成此操作后,需要将其链接到上一个节点,因为它是一个单链接列表,所以需要维护指向上一个节点的指针。如果你想学习,应该能够记住所有的生活,不要看到上面提到的任何代码。试着考虑上面提到的因素,并尝试提出自己的代码 您需要问自己的第一个问题是复制语义是什么。特别是,您正在使用
Student*
作为节点内容。复制节点内容意味着什么?我们是应该复制指针,使两个列表指向(共享)相同的学生实例,还是应该执行一个命令
您应该问自己的下一个问题是如何为第二个列表分配节点。当前,您在副本中仅分配1个节点
我认为您的代码应该更像:
Listnode *SortedList::copyList(Listnode *L) {
Listnode *current = L;
// Assume the list contains at least 1 student.
Listnode *copy = new Listnode;
copy->student = new Student(*current->student);
copy->next = NULL;
// Keep track of first element of the copy.
Listnode *const head = copy;
// 1st element already copied.
current = current->next;
while (current != NULL) {
// Allocate the next node and advance `copy` to the element being copied.
copy = copy->next = new Listnode;
// Copy the node contents; don't share references to students.
copy->student = new Student(*current->student);
// No next element (yet).
copy->next = NULL;
// Advance 'current' to the next element
current = current->next;
}
// Return pointer to first (not last) element.
return head;
}
如果您喜欢在两个列表之间共享学生实例,可以使用
copy->student = current->student;
而不是
copy->student = new Student(*current->student);
正如其他人所指出的,您需要为原始列表中的每个节点调用
new
,为副本分配空间,然后将旧节点复制到新节点,并更新复制节点中的指针
我在这个函数中遇到的另一个因素是返回一个指向局部变量的指针
您没有返回指向局部变量的指针;当您调用
new
时,您在堆上分配了内存并返回了指向该堆的指针(当然这意味着您需要记住在使用新列表时从函数外部调用delete
以释放它)。我一直在尝试做同样的事情。我的要求是:1.每个节点都是一个非常基本和简单的类(我离开了结构模型)。
2.我想创建一个深度副本,而不仅仅是一个指向旧链表的指针
我选择的方式是用下面的C++代码:
template <class T>
Node <T> * copy(Node <T> * rhs)
{
Node <T> * current = new Node<T>();
Node <T> * pHead = current;
for (Node <T> * p = rhs; p; p = p->pNext)
{
Node <T> * prev = current;
prev->data = p->data;
if (p->pNext != NULL)
{
Node <T> * next = new Node<T>();
prev->pNext = next;
current = next;
}
else
{
prev->pNext = NULL;
}
}
return pHead;
}
模板
节点*副本(节点*右侧)
{
节点*当前=新节点();
节点*pHead=电流;
用于(节点*p=rhs;p;p=p->pNext)
{
节点*prev=当前;
上一个->数据=p->数据;
如果(p->pNext!=NULL)
{
Node*next=新节点();
上一页->下一页=下一页;
当前=下一个;
}
其他的
{
prev->pNext=NULL;
}
}
返回pHead;
}
这很好,没有错误。因为“head”是一个特例,所以我需要实现一个“current”指针 +1表示一个很好的问题!第一个反问题:您可以通过分配单个节点复制整个列表吗?第二份、第三份。。。第n个节点的内容将被存储?谢谢,我不确定我是否完全回答了您的问题,但我会尽我所能:-我应该创建一个全新的列表副本。因此,我无法复制标题节点,因为复制的列表将包含相同的引用。我只想复制这些值此外,复制列表中的第一个listnode的值应与原始列表中的第一个listnode的值相同。但复制的列表不应引用/指向原始列表中的任何节点。新列表不应指向旧列表的任何节点,但新节点是否应指向旧内容?本例中的“内容”是“学生”对象。基本上,你也在模仿学生吗?这个问题不清楚。因此,这两个列表可以指向相同的学生,但可以是不同的列表,或者每个列表也可以“拥有”自己的学生副本。不,链接列表的新(复制版本)中不应引用旧链接列表中的任何内容。也就是说,所有新的listnodes都没有指向内存中完全相同的学生或内存中的下一个学生的指针。因为这没有标记为家庭作业,所以请省去一些麻烦,并使用
std::list
。它已经过测试,所以您可以在现在使用调试的时候应用到其他方面,
copy->student = new Student(*current->student);
template <class T>
Node <T> * copy(Node <T> * rhs)
{
Node <T> * current = new Node<T>();
Node <T> * pHead = current;
for (Node <T> * p = rhs; p; p = p->pNext)
{
Node <T> * prev = current;
prev->data = p->data;
if (p->pNext != NULL)
{
Node <T> * next = new Node<T>();
prev->pNext = next;
current = next;
}
else
{
prev->pNext = NULL;
}
}
return pHead;
}