【剑指offer】复杂链表的复制
原创文章,转载请注明出处!
1.题目
输入一个复杂链表,返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)。
- 复杂链表的数据结构
每个节点包含以下三个部分:节点值label,一个指向下一个节点next的指针,一个指向任意一个节点random的特殊指针。
struct RandomListNode
{
int label;
struct RandomListNode *next;
struct RandomListNode *random;
}
- 复杂链表实例(含有5个节点的复杂链表)
2.思路
复杂链表的复制过程分成3个步骤,每个步骤的图形化方式如下:
- 新建复制节点的label和next、random
根据原链表上的每个节点N创建节点N’,然后把创建出来的节点用next连接起来

- 调整复制节点的random

- 拆分链表,其中奇数是原链表,偶数是复制的链表。

3.代码
复杂链表的复制分成三个步骤,每个步骤定义一个子函数。
class Solution {
public:
RandomListNode* Clone(RandomListNode* pHead)
{
// 第一步:复制原链表的节点,label和next
CloneNodes(pHead);
// 第二步:复制原链表的节点,random
ConnectRandom(pHead);
// 第三步:链表拆分,奇数是原链表,偶数是新链表
return ReconnectNodes(pHead);
}
// 第一步
void CloneNodes(RandomListNode* pHead)
{
// 遍历指针
RandomListNode* pNode = pHead;
while(pNode!=nullptr)
{
// 创建节点(节点值)
RandomListNode * pCloned = new RandomListNode(pNode->label);
// 节点指针
pCloned->next = pNode->next;
pCloned->random = pNode->random;
// 节点连接
pNode->next = pCloned;
// 节点移动
pNode = pCloned->next;
}
}
// 第二步
void ConnectRandom(RandomListNode* pHead)
{
// 遍历节点
RandomListNode* pNode=pHead;
RandomListNode* pCloned=nullptr;
while(pNode!=nullptr)
{
// 建立连接
pCloned = pNode->next;
if(pNode->random!=nullptr)
{
pCloned->random = pNode->random->next;
}
pNode = pCloned->next;
}
}
// 第三步
RandomListNode* ReconnectNodes(RandomListNode* pHead)
{
// 遍历指针
RandomListNode* pNode = pHead;
RandomListNode* pClonedHead = nullptr;
RandomListNode* pClonedNode = nullptr;
// 头结点
if(pNode!=nullptr)
{
pClonedHead = pClonedNode = pNode->next;// clone赋值
pNode->next = pClonedNode->next; // node断链
pNode = pNode->next; // node移位
}
// 循环移位
while(pNode!=nullptr)
{
pClonedNode->next = pNode->next; // clone断链
pClonedNode = pClonedNode->next; // clone移位
pNode->next = pClonedNode->next; // node断链
pNode = pNode->next; // node移位
}
return pClonedHead;
}
};


浙公网安备 33010602011771号