【数据结构】复杂链表的复制

链表面试题3:实现一个复杂链表的复制,复杂链表中,每个结点除了有一个pNext指针指向下一个结点外,还有一个pRandom指针指向链表中任一结点或者NULL。

  • 题目分析:

  • 如下图这样的复杂链表,随机指针可能指向结点前面的结点、或者结点后面的结点、也可以指向它自己或者NULL

  • 第一反应可以将复制分为两步,先进行普通单链表的复制,再进行每个结点random随机指针的复制,但random指针可能指向结点的前方,这时就需要从头再遍历找到random指向的结点再进行复制,对于n个结点的链表,若每个结点random都指向前面的结点,这就意味着每个结点都需从头遍历一次,这种方法的时间复杂度为O(n^2),我们需要做进一步的优化。

  • 解题思路:

    • 方法一:

      • 如上题目分析时所提到的方法,但过于复杂,不予推荐

    • 方法二:

      • 1、复制结点:首先复制链表的每一个结点,并将其连接到原链表对应结点的后面,如图所示。

      • 2、复制随机指针:在同时含有原结点和复制结点的链表上,设置复制结点的随机指针的指向。

      • 3、拆分链表:将链表的奇数位置的结点连接行成一个链表即为原链表,再把偶数位置的结点连接起来即为新复制的链表

  • 图解法二

  • 代码实现

RandomListNode* Clone(RandomListNode* pHead)
{
	//当链表为NULL时,直接返回空
	if (pHead == NULL)
	{
		return NULL;
	}

	RandomListNode*pNode = pHead;
	RandomListNode*pClone = NULL;

//链表的连接
	while (pNode != NULL)
	{
		pClone = (RandomListNode*)malloc(sizeof(RandomListNode));
		pClone->label = pNode->label;
		pClone->next = pNode->next;
		pClone->random = NULL;

		pNode->next = pClone;
		pNode = pClone->next;
	}
		
	//随机指向的复制
	pNode = pHead;
	while (pNode != NULL)
	{
		//若random指向NULL,则按照初始化所赋值NULL执行,且pClone移向下一个复制结点
		pClone = pNode->next;//不能放在if内部
			
		if (pNode->random != NULL)
		{
			pClone->random = pNode->random->next;
			pNode = pClone->next;
		}
	}

	//拆分链表
	pNode = pHead;
	RandomListNode*pCloneHead = NULL;
	if (pNode != NULL)
	{
		pCloneHead = pNode->next;
		pClone = pNode->next;
		pNode->next = pClone->next;
		pNode = pNode->next;
	}

	while (pNode != NULL)
	{
		//注意此处拆分顺序,否则会造成数据丢失
		pClone->next = pNode->next;
		pClone = pClone->next;
		pNode->next = pClone->next;
		pNode = pNode->next;
	}
	return pCloneHead;
	}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值