📌  相关文章
📜  克隆带有下一个和随机指针的链表 | 2套

📅  最后修改于: 2022-05-13 01:57:44.026000             🧑  作者: Mango

克隆带有下一个和随机指针的链表 | 2套

我们已经讨论了两种不同的克隆链表的方法。在这篇文章中,讨论了一种更简单的克隆链表的方法。

这个想法是使用哈希。下面是算法。
1、遍历原链表,在数据方面做一份拷贝。
2. 用原始链表节点和复制的链表节点制作键值对的哈希映射。
3. 再次遍历原链表,利用hash map调整克隆链表节点的下一个随机引用。
下面是上述方法的实现。

C++
// C++ program to clone a linked list with
// random pointers
#include
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 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 map = new HashMap();
 
        // 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 map = new Dictionary();
 
        // 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


输出:

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

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程