方法:
/**
* Definition for a Node.
* struct Node {
* int val;
* struct Node *next;
* struct Node *random;
* };
*/
struct Node* copyRandomList(struct Node* head) {
//插入节点
struct Node* cur = head;
while(cur != NULL)
{
//创建复制节点
struct Node* copynode =(struct Node*)malloc(sizeof(struct Node));
copynode->val = cur->val;
//插入
struct Node* next = cur->next;
cur->next = copynode;
copynode->next = next;
cur = next;
}
//链接random
cur = head;
while(cur != NULL)
{
struct Node* copynode = cur->next;
if(cur->random == NULL)
{
copynode->random = NULL;
}
else
{
copynode->random = cur->random->next;
}
cur = copynode->next;
}
//解绑
cur = head;
struct Node* newhead = NULL, *tail = NULL;
while(cur != NULL)
{
struct Node* copynode = cur->next;
if(tail == NULL)
{
newhead = tail = copynode;
}
else
{
tail->next = copynode;
tail = tail->next;
}
cur = copynode->next;
}
return newhead;
}
思路:
想要复制带随机指针的节点,主要难点在于随机指针指向的节点位置不好确认。因此,要想知道每个随机指针指向的节点的位置,可以通过在原链表上赋值节点。即在每个节点后面插入一个和该节点具有一样val的节点。然后复制后的节点可以通过原链表节点找到其random指向的复制节点。最后再将复制的节点取下来,通过链表尾插得到一个完整的复制链表。
复制节点:创建一个指针,通过遍历原链表,在每一个节点后面插入一个复制节点。此时的复制节点的random是随机的,之后再处理。
链接random:每一个复制节点的random的指向是其前一个节点(即被复制的节点)的指向的节点的复制节点。它们的相对位置一致。遍历链表,将每一个复制节点的random指向具体的复制节点。
解绑复制节点:最后将复制节点一个个取下来,尾插到创建的新链表。