cstrike2
cstrike2

Reputation: 55

How to make a copy constructor for a linked list?

I worked through every function in this program, and I mostly get the concepts, but a copy constructor for the linked list has me stumped. I look at other answers regarding this but I don't get how to apply it to my situation.

I have three files, a test.cpp which holds main(), a IntList.cpp and a IntList.h.

test.cpp and IntList.h was provided by my professor, so its safe to assume theres no errors there. I just had to write IntList.cpp.

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


using namespace std;

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

IntList::IntList(const IntList &)
{

    ???

}

Here's IntList.h. Let me know if you need test.cpp or the other functions in 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_ */

EDIT:

I'm reading y'all's comments but it's just not clicking for me.

I tried to rewrite the code and it still wasn't making sense. Here's my attempt, I feel like I just don't get what this is supposed to look like.

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. 

Here's my function for displayList()

void IntList::displayList()
{

    ListNode *nodePtr;

    nodePtr = head;

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

}

And here's my 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;

    }

}

Those made a lot of sense to me and I finished them pretty quickly. I'm not getting how to implement those ideas into the copy constructor. Can y'all help me figure out what I'm not getting?

Upvotes: 0

Views: 1889

Answers (1)

Vlad from Moscow
Vlad from Moscow

Reputation: 310990

Here you are

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

If you have difficulties to understand how to deal with pointers to pointers then I can suggest another constructor definition that does not use pointers to pointers.

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

Upvotes: 1

Related Questions