Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/125.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 编码一个函数以复制C++;_C++_Linked List - Fatal编程技术网

C++ 编码一个函数以复制C++;

C++ 编码一个函数以复制C++;,c++,linked-list,C++,Linked List,我需要实现一个名为copyList的辅助函数,它有一个参数,一个指向ListNode的指针。此函数需要返回指向原始链表副本的第一个节点的指针。换句话说,我需要在C++中编写一个函数,该函数使用链表的头节点并复制整个链表,返回指向新的头节点的指针。我需要帮助实现这个功能,这就是我现在拥有的 Listnode *SortedList::copyList(Listnode *L) { Listnode *current = L; //holds the current node

我需要实现一个名为copyList的辅助函数,它有一个参数,一个指向ListNode的指针。此函数需要返回指向原始链表副本的第一个节点的指针。换句话说,我需要在C++中编写一个函数,该函数使用链表的头节点并复制整个链表,返回指向新的头节点的指针。我需要帮助实现这个功能,这就是我现在拥有的

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;
}