Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ Deep Copying Linked List

First of all, this is part of an assignment I'm currently trying to figure out. I'm trying to create a copy constructor that deep copies a given LinkedList. I have coded the LinkedList methods already.

Here's the necessary parts of the LinkedList.h file.

LinkedList.h
private:
    struct node {
        Val data;
        node* next = nullptr;

    };

    typedef struct node* nodePtr;


    nodePtr head = nullptr;
    nodePtr current = nullptr;
    nodePtr temp = nullptr;
};

The parameters are given: "LinkedList::LinkedList(const LinkedList & ll)" ll is the linked list to be copied. I first tested if there is a head in the linked list, if not then that means the linked list is empty. Then I copied the head from the old list to the new list. I then set the new current to the head in preparation for the while loop. Inside the while loop, I am copying the data of the current node as well as the pointer to the next node. At the end I set the next pointer to nullptr to signify the end of the new list.

LinkedList.cpp

LinkedList::LinkedList(const LinkedList & ll){
    if (ll.head == nullptr) {
        return;
    }
    head = ll.head;
    current = head;


    while (ll.current->next != nullptr) {
        current->data = ll.current->data;
        current->next = ll.current->next;
    }
    current->next = nullptr;
}

I'm not sure if this is deep copying or not. I also know that ll.current's starting position is not at the head. I tried ll.current = ll.head. However, since it is given that this function is const. I can't set it like that.

There is also another function given: LinkedList & LinkedList::operator=(const LinkedList & ll) { } That I suspect may be needed. I'm hoping it optional that I use this.

like image 714
UnseededAndroid Avatar asked Nov 25 '16 05:11

UnseededAndroid


People also ask

What is deep copy of a linked list?

Deep copy of a Linked List means we do not copy the references of the nodes of the original Linked List rather for each node in the original Linked List a new node is created. We create an exact copy of the original list. Notice every node has a new copy.

How do you copy a linked list?

First create a single linked list with only the 'next' pointer and use a mapping to map the new nodes to their corresponding nodes in the given linked list. Now use this mapping to point the arbitrary node from any node in the newly created list.

What is a shallow copy of a linked list?

A linkedlist is just a class with one field which is a ref to a head node. Each node is an individual object which contains a ref to its next. Like you said, a shallow copy doesn't copy the node. So when i add a new node, the current last node's next variable refers to the next node.

How do you create clone of a Linkedlist?

To clone a linked list with random pointers, maintain a hash table for storing the mappings from a linked list node to its clone. We create a new node with the same data for each node in the original linked list and recursively set its next pointers.


2 Answers

You need to allocate new memory or new list elements as you add them, change your code to do the following:

// LinkedList.cpp

LinkedList::LinkedList(const LinkedList & ll)
{
    if (ll.head == nullptr)
        return;

    // Create a temp variable since ll.current doesn't move/change.
    node* tmp = ll.head;

    // Allocate a new node in memory.
    head = new node;
    // Copy over the value.
    head->data = tmp->data;
    // Set the 'next' value to null (the loop will fill this in). 
    head->next = nullptr;
    // Point 'current' to 'head'.
    current = head;
    
    // Move to next item in ll's list.
    tmp = tmp->next;

    while (tmp != nullptr)
    {
        // Allocate new memory for a new 'node'.
        current->next = new node;
        // Point to this new 'node'.
        current = current->next;
        // Copy over the data.
        current->data = tmp->data;
        // By default set the 'next' to null.
        current->next = nullptr;
        // Move along ll's list.
        tmp = tmp->next;
    }
}

Also, in your class get rid of typedef node* nodePtr. There is no need for that, it's cleaner to simply use node* for head, current and temp. Lastly, don't forget in your class' destructor to clear out dynamically allocated memory:

LinkedList::~LinkedList()
{
    current = head;

    while(current != nullptr)
    {
        current = current->next;
        delete head;
        head = current;
    }
}
like image 156
user2205930 Avatar answered Sep 17 '22 23:09

user2205930


This cannot work, as you never allocate new list elements for the actual list object (using the 'new' operator), but only reuse existing ones. Just think about what happens, if ll has more elements than the actual list?

like image 28
Trantor Avatar answered Sep 16 '22 23:09

Trantor