复杂链表的复制

复杂链表的复制是一个难点,但是也是链表面试题的重点。今天我们就来看下复杂链表的赋值。

1. 复杂链表(ComplexList)

template<class T>
struct ComplexListNode
{
	T _data;
	ComplexListNode<T>* pNext;   //next指针域
	ComplexListNode<T>* pRandom; //随机指针域
};

复杂链表的复杂之处在于它多了一个随机指针域(Random),随机指针域的指针可以指向链表的任意位置,包括自己,其他任意一个结点,NULL等。

复杂链表复制的复杂之处就是对于随机指针的处理,在单纯的复制了每一个结点之后,它的随机指针域的指向需要我们分析和寻找,如果每个结点都从头遍历的话,时间复杂度就是O(n^2)。操作也比较困难。

2. 复杂链表的复制

复杂链表的复制分为三步,第一步:将所有结点复制,先不处理结点的随机指针域,将复制后的结点插入到对应结点的后面。

                     

第二步:处理随机指针域:想一下,原链表中结点N的随机指针域指向的结点S,在第一步操作完成后,结点N对应的结点N'的随机指针域指向的结点一定是S’(S'是S的复制结点)。

                    

第三步:将新链表分成两个链表,即原链表和复制后的链表。

                    

3.每一步所对应的代码

typedef ComplexListNode<T> Node;
	typedef Node* pNode;

第一步:复制结点

void ComNodeClone(pNode pHead)
	{
		if (pHead == NULL)
			return;
		pNode pCur = pHead;
		while (pCur != NULL)
		{
			pNode pClone = new Node();
			pClone->_data = pCur->_data;
			pClone->pNext = pCur->pNext;
			pClone->pRandom = NULL;

			pCur->pNext = pClone;

			pCur = pClone->pNext;
		}
	}

第二步:处理随机指针域

//第二步:处理随机指针域

	void SetRandom(pNode pHead)
	{
		if (pHead == NULL)
			return;
		pNode pCur = pHead;
		
		while (pCur != NULL)
		{
			pNode pClone = pCur->pNext;
			if (pCur->pRandom!=NULL)
			   pClone->pRandom = pCur->pRandom->pNext;

			pCur = pClone->pNext;

		}
	}

第三步:分离链表

pNode ReConnectList(pNode pHead)
	{
		pNode pCur = pHead;
		pNode pCloneHead = NULL;
		pNode pCloneNode = NULL;

		if (pCur != NULL)
		{
			pCloneHead = pCloneNode = pCur->pNext;
			pCur->pNext = pCloneNode->pNext;
			pCur = pCur->pNext;
		}

		while (pCur != NULL)
		{
			pCloneNode->pNext = pCur->pNext;
			pCloneNode = pCloneNode->pNext;

			pCur->pNext = pCloneNode->pNext;
			pCur = pCur->pNext;
		}
		return pCloneHead;
	}

整体代码:

#include <iostream>
using namespace std;

template<class T>
struct ComplexListNode
{
	T _data;
	ComplexListNode<T>* pNext;   //next指针域
	ComplexListNode<T>* pRandom; //随机指针域
};

template<class T>
class Solution
{
	typedef ComplexListNode<T> Node;
	typedef Node* pNode;
public:
	pNode ComplexListClone(pNode pHead)
	{
		ComNodeClone( pHead);
		SetRandom( pHead);
		return ReConnectList( pHead);
	}
private:
	//第一步:将所有结点复制,将复制后的结点插入到对应结点的后面
	void ComNodeClone(pNode pHead)
	{
		if (pHead == NULL)
			return;
		pNode pCur = pHead;
		while (pCur != NULL)
		{
			pNode pClone = new Node();
			pClone->_data = pCur->_data;
			pClone->pNext = pCur->pNext;
			pClone->pRandom = NULL;

			pCur->pNext = pClone;

			pCur = pClone->pNext;
		}
	}

	//第二步:处理随机指针域

	void SetRandom(pNode pHead)
	{
		if (pHead == NULL)
			return;
		pNode pCur = pHead;
		
		while (pCur != NULL)
		{
			pNode pClone = pCur->pNext;
			if (pCur->pRandom!=NULL)
			   pClone->pRandom = pCur->pRandom->pNext;

			pCur = pClone->pNext;

		}
	}

	//第三步:分离链表

	pNode ReConnectList(pNode pHead)
	{
		pNode pCur = pHead;
		pNode pCloneHead = NULL;
		pNode pCloneNode = NULL;

		if (pCur != NULL)
		{
			pCloneHead = pCloneNode = pCur->pNext;
			pCur->pNext = pCloneNode->pNext;
			pCur = pCur->pNext;
		}

		while (pCur != NULL)
		{
			pCloneNode->pNext = pCur->pNext;
			pCloneNode = pCloneNode->pNext;

			pCur->pNext = pCloneNode->pNext;
			pCur = pCur->pNext;
		}
		return pCloneHead;
	}
};

 

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值