在复杂链表中,每个节点除了有一个next指向下一个节点,还有一个指向任意节点的指针,他的复制我们要考虑许多因素。
题目:
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)/* struct RandomListNode { int label; struct RandomListNode *next, *random; RandomListNode(int x) : label(x), next(NULL), random(NULL) { } }; */ class Solution { public: RandomListNode* Clone(RandomListNode* pHead) { } };
由题目可知,结构体定义了三个参数,label节点的值,next节点的下一个,random节点的任意指向。它一般的构造形式为:
所以在对复杂链表进行复制时一定要考虑random的复制,但是random具有很大的随机性,对其进行复制,我们很容易遇见问题,于是我们一般采取下面的方式,从而实现对其进行复制:
1、在原有链表的基础上对每个节点进行复制一个相似的节点,从而链接到这个节点的后面,形成一个一致的链表
2、通过上面的节点复制,形成了一条所有节点都是双份的链表,但是random并没有复制成功,因此通过让拷贝节点的random指向原链表节点的random指向的下一个节点,此时random就正确了
3、通过上面两步我们已经将链表的复制完成,但这个链表还与原来的链表连接在一起,此时我们需要将新链表与原链表拆分开,从而形成新的链表。
完整代码
/*
struct RandomListNode {
int label;
struct RandomListNode *next, *random;
RandomListNode(int x) :
label(x), next(NULL), random(NULL) {
}
};
*/
class Solution {
public:
RandomListNode* Clone(RandomListNode* pHead)
{
if(pHead==NULL)
return NULL;
RandomListNode*cur=pHead;
while(cur)//复制节点
{
RandomListNode*newNode=new RandomListNode(cur->label);
newNode->label=cur->label;
newNode->next=NULL;
RandomListNode*next=cur->next;
cur->next=newNode;
newNode->next=next;
cur=next;
}
cur=pHead;
while(cur)//设置新链表的random
{
RandomListNode*copy=cur->next;
if(cur->random==NULL)
{
copy->random=NULL;
}
else
{
copy->random=cur->random->next;
}
cur=cur->next->next;
}
cur=pHead;
RandomListNode*copylist=cur->next;
RandomListNode*tail=cur->next;
cur->next=copylist->next;
cur=cur->next;
while(cur)//链表的拆解
{
RandomListNode*copy=cur->next;
cur->next=copy->next;
tail->next=copy;
tail=copy;
cur=cur->next;
}
return copylist;
}
};