รายการที่เชื่อมโยงเป็นโครงสร้างข้อมูลเชิงเส้นซึ่งแต่ละโหนดมีสองบล็อก โดยที่หนึ่งบล็อกมีค่าหรือข้อมูลของโหนด และอีกบล็อกมีที่อยู่ของฟิลด์ถัดไป
สมมติว่าเรามีรายการที่เชื่อมโยง โดยที่แต่ละโหนดมีตัวชี้สุ่มซึ่งชี้ไปยังโหนดอื่นในรายการ ภารกิจคือการสร้างรายการให้เหมือนกับรายการเดิม การคัดลอกรายการจากรายการต้นฉบับซึ่งมีตัวชี้แบบสุ่มเรียกว่า 'Deep Copy' ของรายการที่เชื่อมโยง
ตัวอย่าง
อินพุต-1

ผลลัพธ์:
5-> 2 -> 3 -> 7 ->4 ->
คำอธิบาย: หากเราผนวกรายการใหม่ด้วยค่าของโหนดดั้งเดิมในรายการเชื่อมโยงที่กำหนดและแทนที่ตัวชี้สุ่มของรายการที่เชื่อมโยงดั้งเดิมด้วยโหนดถัดไปในรายการใหม่ มันจะกลายเป็น 5-> 2->3 -> 7-> 4->
แนวทางในการแก้ปัญหานี้
เรามีรายการที่เชื่อมโยงกับโหนดที่มีข้อมูลและตัวชี้แบบสุ่ม เพื่อให้ได้สำเนาของรายการที่เชื่อมโยงกับข้อมูลและตัวชี้แบบสุ่ม ก่อนอื่นเราจะต่อท้ายโหนดใหม่ด้วยค่าเดียวกันหลังจากแต่ละโหนด สิ่งนี้จะสร้างโหนดที่ซ้ำกันหลังจากแต่ละโหนด
หลังจากการเริ่มต้น ให้ตรวจสอบเส้นทางของตัวชี้สุ่มในรายการ และวางตัวชี้สุ่มตามนั้นในโหนดที่สร้างขึ้นใหม่
ตอนนี้การแยกโหนดที่สร้างขึ้นใหม่หลังจากแต่ละโหนดในรายการดั้งเดิมจะสร้างสำเนาของรายการที่เชื่อมโยงอย่างลึกซึ้ง
- นำรายการที่เชื่อมโยงพร้อมช่องข้อมูลและตัวชี้ไปยังที่อยู่ของโหนดสุ่ม
- ฟังก์ชัน copyRandomList(listnode*head) รับโหนดส่วนหัวของรายการดั้งเดิมเป็นอินพุตและส่งคืนสำเนาแบบลึกของรายการ
- หากส่วนหัวว่างเปล่า แสดงว่ารายการนั้นว่างเปล่า และเราต้องส่งคืนส่วนหัวด้วย
- ตอนนี้แทรกโหนดใหม่ที่มีค่าเดียวกันหลังจากแต่ละโหนดของรายการเดิม
- จากนั้นคัดลอกตัวชี้สุ่มจากรายการต้นฉบับและแทรกโหนดใหม่ นั่นคือ newnode->next =curr->randomPointer
- เมื่อสร้างโหนดใหม่ด้วยตัวชี้และข้อมูล เราจะแยกรายการและส่งคืนรายการเป็นผลลัพธ์
ตัวอย่าง
#include <bits/stdc++.h>
using namespace std;
struct listnode {
int data;
listnode * next, * random;
listnode(int d) {
data = d;
next = NULL;
random = NULL;
}
};
void print(listnode * head) {
listnode * curr = head;
while (curr) {
cout << curr -> data << " " << curr -> random -> data << endl;
curr = curr -> next;
}
}
listnode * copyRandomList(listnode * head) {
if (!head) {
return head;
}
//Insert a new node with the same value after each node in the original list.
listnode * curr = head;
while (curr) {
listnode * newHead = new listnode(curr -> data);
newHead -> next = curr -> next;
curr -> next = newHead;
curr = curr -> next -> next;
}
//Now place the randompointer with the newly created node.
curr = head;
while (curr) {
if (curr -> random)
(curr -> next) -> random = (curr -> random) -> next;
curr = curr -> next -> next;
}
//Now Let us separate the newly created list
curr = head;
listnode * result = curr -> next;
listnode * dummyHead = new listnode(-1);
dummyHead -> next = result;
while (curr) {
curr -> next = result -> next;
curr = curr -> next;
if (curr) {
result -> next = curr -> next;
}
result = result -> next;
}
result = dummyHead -> next;
delete dummyHead;
return result;
}
int main() {
listnode * head = new listnode(5);
head -> next = new listnode(6);
head -> next -> next = new listnode(3);
head -> next -> next -> next = new listnode(4);
head -> next -> next -> next -> next = new listnode(2);
head -> random = head -> next -> next;
head -> next -> random = head;
head -> next -> next -> random =
head -> next -> next -> next -> next;
head -> next -> next -> next -> random =
head -> next -> next -> next -> next;
head -> next -> next -> next -> next -> random =
head -> next;
cout << "Original list :" << endl;
print(head);
cout << "Deep Copy of the List:" << endl;
listnode * deep_copyList = copyRandomList(head);
print(deep_copyList);
return 0;
} การเรียกใช้โค้ดด้านบนจะสร้างผลลัพธ์เป็น
ผลลัพธ์
Original List: 5 3 6 5 3 2 4 2 2 6 Deep Copy of the List: 5 3 6 5 3 2 4 2 2 6