题目:
请实现函数ComplexListNode* Clone(ComplexListNode* pHead),复制一个复杂链表。
在复杂链表中,每个结点除了有一个pNext指针指向下一个结点之外,还有一个pSibling指向链表中的任意结点或者NULL。
结点的定义如下:
struct ComplexListNode{
int val;
ComplexListNode* pNext;
ComplexListNode* pSibling;
};
思路:
- 复制结点
- 复制随机指针
- 重新连接复制的结点
假设给的复杂链表如下:
复制结点
复制随机指针
重新连接复制的结点
class Soultion{
public:
RandomListNode* Clone(RandomListNode* pHead)
{
CloneAllNodes(pHead);//复制结点,并连接在复制的那个结点的后边,它的下一个结点指向我们复制的结点的下一个结点
CloneRandom(pHead);//复制随机指针
return ConnectAllNodes(pHead);//重新连接复制的结点
}
//复制结点,并连接在复制的那个结点的后边,它的下一个结点指向我们复制的结点的下一个结点
void CloneAllNodes(RandomListNode* pHead)
{
RandomListNode* pClone;
while (pHead != NULL)
{
pClone = new RandomListNode(pHead->label);//复制当前的结点
pClone->next = pHead->next;//连接
pHead->next = pClone;
pHead = pClone->next;//指针指向下一个复制的结点
}
}
//复制随机指针
void CloneRandom(RandomListNode* pHead)
{
RandomListNode* pClone;
while (pHead != NULL)
{
pClone = pHead->next;//指向复制的结点
if (pHead->random != NULL)
{
pClone->random = pHead->random->next;//复制的结点的值的random指向当前的结点的random的next结点
}
pHead = pClone->next;
}
}
//重新连接复制的结点
RandomListNode* ConnectAllNodes(RandomListNode* pHead)
{
RandomListNode* pNode = pHead;//指向当前结点的位置
RandomListNode* ClonepHead = NULL;//标记复制链表的头部
RandomListNode* ClonepNode = NULL;//指向复制结点的当前位置
//先处理两个链表的头部
if (pNode != NULL)
{
ClonepNode = pNode->next;
ClonepHead = pNode->next;
pNode->next = ClonepHead->next;
pNode = pNode->next;
}
while (pNode != NULL)
{
ClonepNode->next = pNode->next;
ClonepNode = ClonepNode->next;
pNode->next = ClonepNode->next;
pNode = pNode->next;
}
return ClonepHead;
}
};