Clonar una lista enlazada con puntero siguiente y aleatorio | conjunto 2

Ya hemos discutido 2 formas diferentes de clonar una lista enlazada. En esta publicación, se analiza otro método simple para clonar una lista vinculada. 

La idea es usar Hashing. A continuación se muestra el algoritmo. 

  1. Recorra la lista enlazada original y haga una copia en términos de datos. 
  2. Cree un mapa hash del par de valores clave con el Node de lista enlazada original y el Node de lista enlazada copiado. 
  3. Recorra la lista enlazada original nuevamente y, utilizando el mapa hash, ajuste la referencia siguiente y aleatoria de los Nodes de la lista enlazada clonados.

Complete Interview Preparation - GFG

A continuación se muestra la implementación del enfoque anterior.

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>
  
Producción

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

Complejidad temporal : O(n) 
Espacio auxiliar : O(n)

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *