Open In App

Clone a linked list with next and random pointer | Set 2

Improve
Improve
Like Article
Like
Save
Share
Report

We have already discussed 2 different ways to clone a linked list. In this post, one more simple method to clone a linked list is discussed. 

The idea is to use Hashing. Below is algorithm. 

  1. Traverse the original linked list and make a copy in terms of data. 
  2. Make a hash map of key value pair with original linked list node and copied linked list node. 
  3. Traverse the original linked list again and using the hash map adjust the next and random reference of cloned linked list nodes.

Below is the implementation of above approach.

C++




// C++ program to clone a linked list with
// random pointers
#include<bits/stdc++.h>
using namespace std;
  
  
// Linked List Node
class Node
{
    public:
    int data;//Node data
      
    // Next and random reference
    Node *next, *random;
  
    Node(int data)
    {
        this->data = data;
        this->next = this->random = NULL;
    }
};
  
// linked list class
class LinkedList
{
    public:
    Node *head;// Linked list head reference
  
    LinkedList(Node *head)
    {
        this->head = head;
    }
  
    // push method to put data always at
    // the head in the linked list.
    void push(int data)
    {
        Node *node = new Node(data);
        node->next = head;
        head = node;
    }
  
    // Method to print the list.
    void print()
    {
        Node *temp = head;
        while (temp != NULL)
        {
            Node *random = temp->random;
            int randomData = (random != NULL)?
                         random->data: -1;
            cout << "Data = " << temp->data 
                 << ", ";
            cout << "Random Data = " << 
                 randomData << endl;
            temp = temp->next;
        }
        cout << endl;
    }
  
    // Actual clone method which returns
    // head reference of cloned linked
    // list.
    LinkedList* clone()
    {
        // Initialize two references,
        // one with original list's head.
        Node *origCurr = head;
        Node *cloneCurr = NULL;
  
        // Hash map which contains node 
        // to node mapping of original 
        // and clone linked list.
        unordered_map<Node*, Node*> mymap;
  
        // Traverse the original list and
        // make a copy of that in the 
        // clone linked list.
        while (origCurr != NULL)
        {
            cloneCurr = new Node(origCurr->data);
            mymap[origCurr] = cloneCurr;
            origCurr = origCurr->next;
        }
  
        // Adjusting the original list 
        // reference again.
        origCurr = head;
  
        // Traversal of original list again
        // to adjust the next and random 
        // references of clone list using 
        // hash map.
        while (origCurr != NULL)
        {
            cloneCurr = mymap[origCurr];
            cloneCurr->next = mymap[origCurr->next];
            cloneCurr->random = mymap[origCurr->random];
            origCurr = origCurr->next;
        }
  
        // return the head reference of 
        // the clone list.
        return new LinkedList(mymap[head]);
    }
};
  
// driver code
int main()
{
    // Pushing data in the linked list.
    LinkedList *mylist = new LinkedList(new Node(5));
    mylist->push(4);
    mylist->push(3);
    mylist->push(2);
    mylist->push(1);
  
    // Setting up random references.
    mylist->head->random = mylist->head->next->next;
  
    mylist->head->next->random =
        mylist->head->next->next->next;
  
    mylist->head->next->next->random =
        mylist->head->next->next->next->next;
  
    mylist->head->next->next->next->random =
        mylist->head->next->next->next->next->next;
  
    mylist->head->next->next->next->next->random =
        mylist->head->next;
  
    // Making a clone of the original
    // linked list.
    LinkedList *clone = mylist->clone();
  
    // Print the original and cloned 
    // linked list.
    cout << "Original linked list\n";
    mylist->print();
    cout << "\nCloned linked list\n";
    clone->print();
}
// This code is contributed by Chhavi


Java




// Java program to clone a linked list with random pointers
import java.util.HashMap;
import java.util.Map;
  
// Linked List Node class
class Node
{
    int data;//Node data
    Node next, random;//Next and random reference
  
    //Node constructor
    public Node(int data)
    {
        this.data = data;
        this.next = this.random = null;
    }
}
  
// linked list class
class LinkedList
{
    Node head;//Linked list head reference
  
    // Linked list constructor
    public LinkedList(Node head)
    {
        this.head = head;
    }
  
    // push method to put data always at the head
    // in the linked list.
    public void push(int data)
    {
        Node node = new Node(data);
        node.next = this.head;
        this.head = node;
    }
  
    // Method to print the list.
    void print()
    {
        Node temp = head;
        while (temp != null)
        {
            Node random = temp.random;
            int randomData = (random != null)? random.data: -1;
            System.out.println("Data = " + temp.data +
                               ", Random data = "+ randomData);
            temp = temp.next;
        }
    }
  
    // Actual clone method which returns head
    // reference of cloned linked list.
    public LinkedList clone()
    {
        // Initialize two references, one with original
        // list's head.
        Node origCurr = this.head, cloneCurr = null;
  
        // Hash map which contains node to node mapping of
        // original and clone linked list.
        Map<Node, Node> map = new HashMap<Node, Node>();
  
        // Traverse the original list and make a copy of that
        // in the clone linked list.
        while (origCurr != null)
        {
            cloneCurr = new Node(origCurr.data);
            map.put(origCurr, cloneCurr);
            origCurr = origCurr.next;
        }
  
        // Adjusting the original list reference again.
        origCurr = this.head;
  
        // Traversal of original list again to adjust the next
        // and random references of clone list using hash map.
        while (origCurr != null)
        {
            cloneCurr = map.get(origCurr);
            cloneCurr.next = map.get(origCurr.next);
            cloneCurr.random = map.get(origCurr.random);
            origCurr = origCurr.next;
        }
  
        //return the head reference of the clone list.
        return new LinkedList(map.get(this.head));
    }
}
  
// Driver Class
class Main
{
    // Main method.
    public static void main(String[] args)
    {
        // Pushing data in the linked list.
        LinkedList list = new LinkedList(new Node(5));
        list.push(4);
        list.push(3);
        list.push(2);
        list.push(1);
  
        // Setting up random references.
        list.head.random = list.head.next.next;
        list.head.next.random =
            list.head.next.next.next;
        list.head.next.next.random =
            list.head.next.next.next.next;
        list.head.next.next.next.random =
            list.head.next.next.next.next.next;
        list.head.next.next.next.next.random =
            list.head.next;
  
        // Making a clone of the original linked list.
        LinkedList clone = list.clone();
  
        // Print the original and cloned linked list.
        System.out.println("Original linked list");
        list.print();
        System.out.println("\nCloned linked list");
        clone.print();
    }
}


Python3




# Python3 program to clone a linked list 
# with random pointers 
class Node: 
    def __init__(self, data):
          
        # Node Data
        self.data = data 
          
        # Node Next
        self.next = None 
          
        # Node Random
        self.random = None 
  
# Dictionary
class MyDictionary(dict): 
  
    # __init__ function
    def __init__(self):
          
        super().__init__()
        self = dict()
  
        # Function to add key:value
    def add(self, key, value):
          
        # Adding Values to dictionary
        self[key] = value 
  
# Linked list class 
class LinkedList:
      
    # Linked list constructor
    def __init__(self, node):
        self.head = node
  
    # Method to print the list.
    def __repr__(self):
          
        temp = self.head
        while temp is not None:
            random = temp.random
            random_data = (random.data if 
                           random is not None else -1)
                             
            data = temp.data
            print(
                f"Data-{data}, Random data: {random_data}")
            temp = temp.next
              
        return "\n"
  
    # push method to put data always at the head
    # in the linked list.
    def push(self, data):
          
        node = Node(data)
        node.next = self.head
        self.head = node
  
    # Actual clone method which returns head
    # reference of cloned linked list.
    def clone(self):
          
        # Initialize two references, one 
        # with original list's head.
        original = self.head
        clone = None
  
        # Initialize two references, one 
        # with original list's head.
        mp = MyDictionary()
  
        # Traverse the original list and 
        # make a copy of that
        # in the clone linked list
        while original is not None:
            clone = Node(original.data)
            mp.add(original, clone)
            original = original.next
  
        # Adjusting the original 
        # list reference again.
        original = self.head
  
        # Traversal of original list again
        # to adjust the next and random 
        # references of clone list using hash map.
        while original is not None:
            clone = mp.get(original)
            clone.next = mp.get(original.next)
            clone.random = mp.get(original.random)
            original = original.next
              
        # Return the head reference of the clone list.
        return LinkedList(self.head)
  
# Driver code
  
# Pushing data in the linked list.
l = LinkedList(Node(5))
l.push(4)
l.push(3)
l.push(2)
l.push(1)
  
# Setting up random references.
l.head.random = l.head.next.next
l.head.next.random = l.head.next.next.next
l.head.next.next.random = l.head.next.next.next.next
l.head.next.next.next.random = (l.head.next.next.next.
                                  next.next)
l.head.next.next.next.next.random = l.head.next
  
# Making a clone of the 
# original linked list.
clone = l.clone()
  
# Print the original and cloned
# linked list.s
print("Original linked list")
print(l)
print("Cloned linked list")
print(clone)
  
# This code is contributed by ashwinathappan


C#




// C# program to clone a linked list with random pointers
using System;
using System.Collections;
using System.Collections.Generic;
  
class GFG
{
      
// Linked List Node class
public class Node
{
    public int data;// Node data
    public Node next, random;// Next and random reference
  
    // Node constructor
    public Node(int data)
    {
        this.data = data;
        this.next = this.random = null;
    }
}
  
// linked list class
public class LinkedList
{
    public Node head;// Linked list head reference
  
    // Linked list constructor
    public LinkedList(Node head)
    {
        this.head = head;
    }
  
    // push method to Add data always at the head
    // in the linked list.
    public void push(int data)
    {
        Node node = new Node(data);
        node.next = this.head;
        this.head = node;
    }
  
    // Method to print the list.
    public void print()
    {
        Node temp = head;
        while (temp != null)
        {
            Node random = temp.random;
            int randomData = (random != null)? random.data: -1;
            Console.WriteLine("Data = " + temp.data +
                            ", Random data = "+ randomData);
            temp = temp.next;
        }
    }
  
    // Actual clone method which returns head
    // reference of cloned linked list.
    public LinkedList clone()
    {
        // Initialize two references, one with original
        // list's head.
        Node origCurr = this.head, cloneCurr = null;
  
        // Hash map which contains node to node mapping of
        // original and clone linked list.
        Dictionary<Node, Node> map = new Dictionary<Node, Node>();
  
        // Traverse the original list and make a copy of that
        // in the clone linked list.
        while (origCurr != null)
        {
            cloneCurr = new Node(origCurr.data);
            map.Add(origCurr, cloneCurr);
            origCurr = origCurr.next;
        }
  
        // Adjusting the original list reference again.
        origCurr = this.head;
  
        // Traversal of original list again to adjust the next
        // and random references of clone list using hash map.
        while (origCurr != null)
        {
            cloneCurr = map[origCurr];
            if(origCurr.next != null)
                cloneCurr.next = map[origCurr.next];
            if(origCurr.random != null)
                cloneCurr.random = map[origCurr.random];
            origCurr = origCurr.next;
        }
  
        // return the head reference of the clone list.
        return new LinkedList(map[this.head]);
    }
}
  
// Driver code
public static void Main(String []args)
{
    // Pushing data in the linked list.
    LinkedList list = new LinkedList(new Node(5));
    list.push(4);
    list.push(3);
    list.push(2);
    list.push(1);
  
    // Setting up random references.
    list.head.random = list.head.next.next;
    list.head.next.random =
        list.head.next.next.next;
    list.head.next.next.random =
        list.head.next.next.next.next;
    list.head.next.next.next.random =
        list.head.next.next.next.next.next;
    list.head.next.next.next.next.random =
        list.head.next;
  
    // Making a clone of the original linked list.
    LinkedList clone = list.clone();
  
    // Print the original and cloned linked list.
    Console.WriteLine("Original linked list");
    list.print();
    Console.WriteLine("\nCloned linked list");
    clone.print();
}
}
  
// This code is contributed by Arnab Kundu


Javascript




<script>
  
// JavaScript program to clone a linked 
// list with random pointers
  
// Linked List Node class
class Node
{
    constructor(data)
    {
        this.data=data;
        this.next = this.random = null;
    }
}
  
class LinkedList
{
      
      
    // Linked list constructor
    constructor(head)
      
    {
        this.head = head;
    }
      
    // push method to put data always at the head
    // in the linked list.
    push(data)
    {
        let node = new Node(data);
        node.next = this.head;
        this.head = node;
    }
      
    // Method to print the list.
    print()
    {
        let temp = this.head;
        while (temp != null)
        {
            let random = temp.random;
            let randomData = (random != null)? random.data: -1;
            document.write("Data = " + temp.data +
                               ", Random data = "
                               randomData+"<br>");
            temp = temp.next;
        }
    }
      
    // Actual clone method which returns head
    // reference of cloned linked list.
    clone()
    {
        // Initialize two references, one with original
        // list's head.
        let origCurr = this.head, cloneCurr = null;
    
        // Hash map which contains node to node mapping of
        // original and clone linked list.
        let map = new Map();
    
        // Traverse the original list and make a copy of that
        // in the clone linked list.
        while (origCurr != null)
        {
            cloneCurr = new Node(origCurr.data);
            map.set(origCurr, cloneCurr);
            origCurr = origCurr.next;
        }
    
        // Adjusting the original list reference again.
        origCurr = this.head;
    
        // Traversal of original list again to adjust the next
        // and random references of clone list using hash map.
        while (origCurr != null)
        {
            cloneCurr = map.get(origCurr);
            cloneCurr.next = map.get(origCurr.next);
            cloneCurr.random = map.get(origCurr.random);
            origCurr = origCurr.next;
        }
    
        //return the head reference of the clone list.
        return new LinkedList(map.get(this.head));
    }
}
  
// Driver Class
// Pushing data in the linked list.
let list = new LinkedList(new Node(5));
list.push(4);
list.push(3);
list.push(2);
list.push(1);
  
// Setting up random references.
list.head.random = list.head.next.next;
list.head.next.random =
list.head.next.next.next;
list.head.next.next.random =
list.head.next.next.next.next;
list.head.next.next.next.random =
list.head.next.next.next.next.next;
list.head.next.next.next.next.random =
list.head.next;
  
// Making a clone of the original linked list.
let clone = list.clone();
  
// Print the original and cloned linked list.
document.write("Original linked list<br>");
list.print();
document.write("<br>Cloned linked list<br>");
clone.print();
  
// This code is contributed by avanitrachhadiya2155
  
</script>
  


Output

Original linked list
Data = 1, Random Data = 3
Data = 2, Random Data = 4
Data = 3, Random Data = 5
Data = 4, Random Data = -1
Data = 5, Random Data = 2


Cloned linked list
Data = 1, Random Data = 3
Data = 2, Random Data = 4
Data = 3, Random Data = 5
Data = 4, Random Data = -1
Data = 5, Random Data = 2

Time complexity : O(n) 
Auxiliary space : O(n)



Last Updated : 10 Jan, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads