0、题目描述
1、法1
我的第一个想法是,直接把random指针看成一个结构体成员,我创建节点的时候加一个结构体成员不就可以了吗?指针不也是一个地址数据吗?
实际上指针是具有结构特点的,如果按照我的想法复制,random是空的时候没问题,不是空的时候random指针不是指向新链表里面的结构,还是指向原来链表的结构,这条路走不通。
copy链表和原链表得先建立联系,把每一个节点复制在原节点的后面,这样的好处是:
copy链表的random,等于原链表的random的next。 如图。
复制完copy里面的random之后,再把copy链表给解下来,还原原链表。
1、拷贝到每个节点的后面,组成两倍长度的新链表
2、复制里面的random
3、解开copy链表
c
/**
* Definition for a Node.
* struct Node {
* int val;
* struct Node *next;
* struct Node *random;
* };
*/
struct Node* BuyNewNode(int val)
{
struct Node* newnode = (struct Node*)malloc(sizeof(struct Node));
newnode->val = val;
newnode->next = NULL;
newnode->random = NULL;
return newnode;
}
struct Node* copyRandomList(struct Node* head)
{
if (head == NULL)
return NULL;
struct Node* cur = head;
struct Node* newnode = NULL;
struct Node* next = NULL;
//把每个节点放在原节点的后面
while (cur)
{
next = cur->next;
newnode = BuyNewNode(cur->val);
cur->next = newnode;
newnode->next = next;
cur = next;
}
cur = head;
struct Node* newlist = cur->next;
struct Node* newcur = newlist;
while (cur)
{
//复制节点的random,上一个节点random的next
if (cur->random == NULL)
{
newcur->random = NULL;
}
else
{
newcur->random = cur->random->next;
}
//复制完random之前不能动cur->next
cur = cur->next->next;
if (cur)
newcur = newcur->next->next;
}
//解开
cur = head;
newcur = newlist = cur->next;
while (cur)
{
cur->next = newcur->next;
cur = cur->next;
if (cur)
{
newcur->next = cur->next;
newcur = newcur->next;
}
}
return newlist;
}
这里注意newcur可能会越界,所以要 if 拦截一下,cur走到头的时候,不要让newcur再走了!