要完成一个带随机指针的链表的复制,有一个巧妙的办法: 分三步走
代码的实现逻辑: 需要用到三个循环
假设初始链表如下
第一个循环:
经过第一轮循环后,原链表每个节点之后被插入了一个新节点
这一部分的实现代码如下
/**
* Definition for a Node.
* struct Node {
* int val;
* struct Node *next;
* struct Node *random;
* };
*/
typedef struct Node Node;
struct Node* copyRandomList(struct Node* head)
{
Node* pcur=head;
while(pcur)
{
Node*copy=(Node*)malloc(sizeof(Node));//创建拷贝节点
copy->val=pcur->val;//拷贝数据
copy->next=pcur->next;//插入到pcur后面
pcur->next=copy;
pcur=copy->next;//移动pcur指针
}
}
注意:
随机指针不是单纯的拷贝,而是将拷贝节点的随机指针指向与原链表中关系对应的拷贝节点
第二个循环:
这一部分实现代码如下
pcur=head;//指针重置
while(pcur)//链表随机指针拷贝
{
Node*copy=pcur->next;
if(pcur->random==NULL)
copy->random=NULL;//对指向NULL的情况额外处理
else
{
copy->random=pcur->random->next;//随机指针拷贝的关键
}
pcur=copy->next;
}
第三个循环:
这一部分的实现代码如下
别忘记拷贝完成之后,返回新链表的地址
pcur=head;
Node*newhead=NULL,*newtail=NULL;
while(pcur)
{
Node*copy=pcur->next;//指向要拷贝的节点
Node*next=copy->next;//指向原链表原本的下一个节点
if(newhead==NULL)//将拷贝节点尾插到新链表上
{
newhead=newtail=copy;
}
else
{
newtail->next=copy;
newtail=copy;
}
pcur->next=next;//恢复原链表
pcur=next;
}
return newhead;
/**
* Definition for a Node.
* struct Node {
* int val;
* struct Node *next;
* struct Node *random;
* };
*/
typedef struct Node Node;
struct Node* copyRandomList(struct Node* head)
{
Node* pcur=head;
while(pcur)//链表数据拷贝
{
Node*copy=(Node*)malloc(sizeof(Node));//创建拷贝节点
copy->val=pcur->val;//拷贝数据
copy->next=pcur->next;//插入到pcur后面
pcur->next=copy;
pcur=copy->next;//移动pcur指针
}
pcur=head;//指针重置
while(pcur)//链表随机指针拷贝
{
Node*copy=pcur->next;
if(pcur->random==NULL)
copy->random=NULL;//对指向NULL的情况额外处理
else
{
copy->random=pcur->random->next;//随机指针拷贝的关键
}
pcur=copy->next;
}
pcur=head;
Node*newhead=NULL,*newtail=NULL;
while(pcur)
{
Node*copy=pcur->next;//指向要拷贝的节点
Node*next=copy->next;//指向原链表原本的下一个节点
if(newhead==NULL)//将拷贝节点尾插到新链表上
{
newhead=newtail=copy;
}
else
{
newtail->next=copy;
newtail=copy;
}
pcur->next=next;//恢复原链表
pcur=next;
}
return newhead;
}