复杂链表的复制

题目描述

输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)

解题思路:
        1、复制每个节点,并将该结点的复制结点插入到该结点后面,
        如:链表为:A->B->C->D, 经过复制步骤后的链表为:A->A1->B->B1->C->C1->D->D1
        2、遍历链表,A1->random = A->random->next;
        3、将链表拆分成原链表和复制后的链表

假设链表为:1-->2-->3 ,1,2,3代表结点的值,结点值为1结点的random指针指向3,  3的random指针指向2

第一步:复制每个节点,并将该结点的复制结点插入到该结点后面

while(pCurrent)
		{
			RandomListNode *pCloned = new RandomListNode(pCurrent->label);
			pCloned->next = pCurrent->next;
			pCurrent->next = pCloned;
			pCurrent = pCloned->next;
		}

复制后的结点如下图:pHead始终指向原始链表的头结点


第二步:根据每个结点的Random指针情况处理每个复制结点的Random指针
      前一个步骤结束后,pCurrent指向结点的尾部,下一步应从头开始处理

		pCurrent = pHead;
		while(pCurrent)
		{
			RandomListNode *pCloned = pCurrent->next;
			if(pCurrent->random)
			{
				pCloned->random = pCurrent->random->next;
			}
			pCurrent = pCloned->next;
		}

第一幅图为第二步完成后的链表结构图,复制结点的random指针指向如第二幅图所示

第三步:将链表的原始结点与复制结点断开,并使原始结点构成一个链表,复制结点构成一个链表
              进行下一步pCurrent应从头开始,此步骤改变的是结点的next指针的指向,并没有改变random指针

		pCurrent = pHead;
		RandomListNode *pClonedHead = pHead->next;
		RandomListNode *pCurrentCloned = NULL;
		while(pCurrent->next)
		{
			pCurrentCloned = pCurrent->next;
			pCurrent->next = pCurrentCloned->next;
			pCurrent = pCurrentCloned;
		}




 该步骤的第一次处理后链表next指针结构图为: 

处理完后的链表next指针结构图为:

该题完整c++代码:

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)return NULL;
		RandomListNode *pCurrent = pHead;
		//将每个节点复制并插入到该结点的后面
		while(pCurrent)
		{
			RandomListNode *pCloned = new RandomListNode(pCurrent->label);
			pCloned->next = pCurrent->next;
			pCurrent->next = pCloned;
			pCurrent = pCloned->next;
		}
		//根据每个结点的Random指针情况处理每个复制结点的Random指针
		//前一个步骤结束后,pCurrent指向结点的尾部,下一步应从头开始处理
		pCurrent = pHead;
		while(pCurrent)
		{
			RandomListNode *pCloned = pCurrent->next;
			if(pCurrent->random)
			{
				pCloned->random = pCurrent->random->next;
			}
			pCurrent = pCloned->next;
		}
		//将链表的原始结点与复制结点断开,并使原始结点构成一个链表,复制结点构成一个链表
        //此步骤改变的是next指针的指向,并没有改变random指针的指向
		//进行下一步pCurrent应从头开始
		pCurrent = pHead;
		RandomListNode *pClonedHead = pHead->next;
		RandomListNode *pCurrentCloned = NULL;
		while(pCurrent->next)
		{
			pCurrentCloned = pCurrent->next;
			pCurrent->next = pCurrentCloned->next;
			pCurrent = pCurrentCloned;
		}
		return pClonedHead;
    }
};


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值