所谓复杂链表,指的是:
每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点(可以指向自己,可以为空)。
结构如下:
struct RandomListNode
{
RandomListNode(int x)
:label(x)
, next(NULL)
, random(NULL)
{}
int label;//节点的值
struct RandomListNode *next;//指向下一个节点
struct RandomListNode *random;//指向任意节点(可以指向自己,可以为空)
};
现在有一个复杂链表:
这个链表:
节点1的random指节点2;
节点2的random指向节点4;
节点3的random指向节点2;
节点4的random指向自己;
节点5的random为空。
如何复制复杂链表?分三步:
一:把要拷贝的节点插入这个链表
如图所示,被红色圈住的节点表示要新拷贝的节点,它们的random默认为空。
二:可以发现,每一个要新拷贝的节点,它的random等于所对应旧节点random的下一个,所以可以赋值。
三:把新旧节点分开,就可实现复杂链表的复制:
具体方法有很多,我介绍一种:
cur = pHead;
Node* newhead = NULL;//新链表的头
Node* newtail = NULL;//新链表的尾
while (cur)
{
Node* copy = cur->next;//新节点
Node* next = copy->next;//记录cur的下一个节点
cur->next = next;//跳过copy
if (newhead == NULL)
{
newhead = copy;
newtail = copy;
}
else
{
newtail->next = copy;
newtail = copy;
}
cur = next;
}
完整代码:
/复杂链表的复制
RandomListNode* Clone(RandomListNode* pHead)
{
typedef RandomListNode Node;
//1.把1 2 3 4 5变为1 1 2 2 3 3 4 4 5 5
Node* cur = pHead;
while (cur)
{
Node* next = cur->next;
Node* copy = new Node(cur->label);
cur->next = copy;
copy->next = next;
cur = next;
}
//2.此时,新节点的radom就是旧节点radom的下一个,然后置新节点的radom
cur = pHead;
while (cur)
{
Node* copy = cur->next;
if (cur->random != NULL)
{
copy->random = cur->random->next;
}
cur = copy->next;
}
//3.分开
cur = pHead;
Node* newhead = NULL;//新链表的头
Node* newtail = NULL;//新链表的尾
while (cur)
{
Node* copy = cur->next;
Node* next = copy->next;
cur->next = next;
if (newhead == NULL)
{
newhead = copy;
newtail = copy;
}
else
{
newtail->next = copy;
newtail = copy;
}
cur = next;
}
return newhead;
}