如何为链表制作复制构造函数?

How to make a copy constructor for a linked list?

提问人:cstrike2 提问时间:4/19/2020 最后编辑:cstrike2 更新时间:4/19/2020 访问量:1472

问:

我遍历了这个程序中的每个函数,我基本上都理解了这些概念,但是链表的复制构造函数让我难住了。我查看了有关此的其他答案,但我不知道如何将其应用于我的情况。

我有三个文件,一个包含 main() 的test.cpp,一个 IntList.cpp 和一个 IntList.h。

test.cpp 和 IntList.h 是由我的教授提供的,所以可以安全地假设那里没有错误。我只需要写IntList.cpp。

#include <iostream>
#include <cstdlib>
#include "IntList.h"


using namespace std;

IntList::IntList()
{
    head = NULL;
}

IntList::IntList(const IntList &)
{

    ???

}

这里是 IntList.h。如果您需要test.cpp或其他功能,请告诉我IntList.cpp。

// Specification file for the IntList class
#ifndef INTLIST_H
#define INTLIST_H

class IntList
{
private:
   // Declare a structure for the list
   struct ListNode
   {
      int value;
      struct ListNode *next;
   };

   ListNode *head;   // List head pointer

public:
   // Constructor
   IntList();

   // Copy constructor
   IntList(const IntList &);

   // Destructor
   ~IntList();

   // List operations
   void appendNode(int val);
   void removeByVal(int val);
   void displayList();
   void insertByPos(int val, int pos);
   void removeByPos(int pos);
   int search(int val);
};

#endif /* INTLIST_H_ */

编辑:

我正在阅读你们的评论,但它只是没有点击我。

我试图重写代码,但它仍然没有意义。这是我的尝试,我觉得我只是不明白这应该是什么样子。

IntList::IntList(const IntList &list) // maybe I name it list so I can refer to list.head?
{
     ListNode *nodePtr;
     nodePtr = list.head;

     if (nodePtr == NULL) // If the head of list is empty then theres no list to copy
     { 
          return;
     }

     while (nodePtr->next != 0) // Trying to iterate through the link
     {
          nodePtr = nodePtr->next;
     }

     ListNode *newNode;   
     nodePtr->next = newNode; 

     // ??? Confused again. 

这是我的 displayList() 函数

void IntList::displayList()
{

    ListNode *nodePtr;

    nodePtr = head;

    while (nodePtr != NULL)
    {
        cout << nodePtr->value << endl;
        nodePtr = nodePtr->next;
    }

}

这是我的 appendNode()。

void IntList::appendNode(int val)
{

    ListNode *newNode;
    ListNode *nodePtr;

    newNode = new ListNode;
    newNode->value = val;
    newNode->next = NULL;


    if (!head)
    {
        head = newNode;
    }
    else
    {

        nodePtr = head;

        while (nodePtr->next != 0)
        {
            nodePtr = nodePtr->next;
        }

        nodePtr->next = newNode;

    }

}

这些对我来说很有意义,我很快就完成了它们。我不知道如何将这些想法实现到复制构造函数中。你们能帮我弄清楚我没有得到什么吗?

C++ Linked-List 复制构造函数 singly-linked-list

评论

2赞 Igor Tandetnik 4/19/2020
既然你已经实现了,你就知道如何遍历一个列表。既然你已经实现了,你就知道如何添加一个节点了。因此,遍历作为参数传递给复制构造函数的列表,并将具有相同值的节点插入到列表中。displayListappendNodethis
0赞 WhozCraig 4/19/2020
还记得链表最初是如何构建的吗?一次一个节点。枚举该列表,为每个节点创建一个复制目标,在本例中,您可以枚举源,并为每个节点在复制目标上触发 (this)。无关,与您的主张相反,我发现几乎不可能相信对 [cpp] 链表复制构造函数的简单搜索没有任何用处。appendNode
0赞 cstrike2 4/19/2020
我添加了一个编辑,试图更好地解释我的困惑。我想我没有得到需要用复制构造函数做些什么不同的事情,以及什么可以保持与我之前所做的功能相同。@IgorTandetnik
0赞 cstrike2 4/19/2020
我添加了一个编辑,试图更好地解释我的困惑。我在这里找到了复制构造函数的其他示例,但让我感到困惑的是,对于我的 .h 文件,我只有 *head 和 *next 指针可以使用。我可以做像list.head->next这样的事情并重复它或其他什么吗?我没有得到这个概念,我的教科书和在线示例似乎都没有缓解它。我敢肯定这些东西很简单,我知道。@WhozCraig

答:

1赞 Vlad from Moscow 4/19/2020 #1

给你

IntList::IntList( const IntList &list ) : head( nullptr )
{
    ListNode **new_node = &this->head;

    for ( auto current = list.head; current != nullptr; current = current->next )
    {
        *new_node = new ListNode { current->value, nullptr };
        new_node = &( *new_node )->next; 
    }         
}

如果您难以理解如何处理指向指针的指针,那么我可以建议另一个不使用指向指针的指针的构造函数定义。

IntList::IntList( const IntList &list ) : head( nullptr )
{
    if ( list.head != nullptr )
    {
        this->head = new ListNode { list.head->value, nullptr };

        for ( auto new_node = this->head, current = list.head->next;
              current != nullptr;
              new_node = new_node->next, current = current->next )
        {
            new_node->next = new ListNode { current->value, nullptr };
        }             
    }
}

评论

0赞 cstrike2 4/19/2020
谢谢!这确实有一点帮助