Write a function that takes a singly linked list and returns a complete copy of that list.

Practice this problem

1. Naive Approach

The idea is to iterate over the original list in the usual way and maintain two pointers to keep track of the new list: one head pointer and one tail pointer, which always points to the last node of the new list. The first node is done as a special case, and then the tail pointer is used in the standard way for the others.

This approach is demonstrated below in C, Java, and Python:

C


Download  Run Code

Output:

1 —> 2 —> 3 —> 4 —> NULL

Java


Download  Run Code

Output:

1 —> 2 —> 3 —> 4 —> null

Python


Download  Run Code

Output:

1 —> 2 —> 3 —> 4 —> None

2. Using push() function

The above implementation is a little unsatisfying because the 3–step link-in is repeated – once for the first node and once for all the other nodes. The following C, Java, and Python implementation uses push() to allocate and insert the new nodes and avoid repeating that code.

C


Download  Run Code

Output:

1 —> 2 —> 3 —> 4 —> NULL

Java


Download  Run Code

Output:

1 —> 2 —> 3 —> 4 —> null

Python


Download  Run Code

Output:

1 —> 2 —> 3 —> 4 —> None

3. Using Dummy Node

Another strategy is to use a temporary dummy node to take care of the first node case. The dummy node is temporarily the first node in the list, and the tail pointer starts off pointing to it. All nodes are added off the tail pointer.

Following is the C, Java, and Python implementation of the idea:

C


Download  Run Code

Output:

1 —> 2 —> 3 —> 4 —> NULL

Java


Download  Run Code

Output:

1 —> 2 —> 3 —> 4 —> null

Python


Download  Run Code

Output:

1 —> 2 —> 3 —> 4 —> None

4. Using Local References

The final and most unusual version uses the “local references” strategy instead of a tail pointer. The strategy is to keep a lastPtr that points to the last pointer in the list. All node additions are made at the lastPtr, and it always points to the last pointer in the list. When the list is empty, it points to the head pointer itself. Later it points to the .next pointer inside the last node in the list.

The implementation can be seen below in C:

C


Download  Run Code

Output:

1 —> 2 —> 3 —> 4 —> NULL

5. Recursive Solution

Finally, for completeness, following is the recursive version of copyList() in C, Java, and Python. It has the pleasing shortness that recursive code often has. However, it is probably not good for production code since it uses stack space proportional to its list length.

C


Download  Run Code

Output:

1 —> 2 —> 3 —> 4 —> NULL

Java


Download  Run Code

Output:

1 —> 2 —> 3 —> 4 —> null

Python


Download  Run Code

Output:

1 —> 2 —> 3 —> 4 —> None

Source: http://cslibrary.stanford.edu/103/LinkedListBasics.pdf