《剑指offer》:[26]复杂链表的复制

题目;请实现函数ComplexListNode *Clone(ComplexListNode *pHead),复制一个复杂链表。在复杂链表中,每一个结点除了有一个m_pNext指针指向下一个结点外,还有一个m_pString指向链表中的任意结点或者NULL。
复杂链表的结构如下:
struct ComplexList
{
int data;
ComplexList *pNext;
ComplexList *pOther;
};
方案一:复制原链表上的每一个结点并用pNext连接起来;然后再设置pOther指针;但是由于node的pOther可能指向该结点的前面也可能指向该结点的后面,所以每次需要遍历链表找到该结点,所以其时间复杂度为O(N^2)。
方案二:由于需要快速定位pOther指针的位置,所以我们可以借助一个辅助空间哈希表来存储<N,N1>的映射关系,N表示原链表的结点,N1表示新复制的链表的位置。这样我们在定位pOther指针指向的数据的时候可以在O(1)的时间找到任何一个结点的位置。但是需要O(N)的辅助空间,相当于用空间换取了时间。
方案三:我们可以用O(1)的时间来完成且不需要辅助空间。具体实现过程如下所示:

具体实现代码如下:
#include <iostream>
using namespace std;
struct ComplexList
{
	int data;
	ComplexList *pNext;
	ComplexList *pOther;
};
int arr[5]={7,3,5,2,9};
ComplexList *pHead=NULL;
ComplexList *pEnd=NULL;

void CreateListhelp(ComplexList **head,int data)
{
	ComplexList  *pNode=new ComplexList;
	pNode=new ComplexList;
	pNode->data=data;
	pNode->pNext=pNode->pOther=NULL;
	if(NULL==*head)
	{
		*head=pNode;
		pEnd=*head;
	}
	else
	{
		pEnd->pNext=pNode;
		pEnd=pNode;
	}
}
void CreateList(ComplexList **head,int *array,int length)
{
	for(int i=0;i<length;i++)
		CreateListhelp(head,array[i]);
}
void show(ComplexList *list)
{
	ComplexList *temp=list;
	while(temp)
	{
		cout<<temp->data<<" ";
		temp=temp->pNext;
	}
	cout<<endl;
}
void Set_pOther(ComplexList *list)
{//设置指向任意结点的指针;1->3;2->4;3->5;
	ComplexList *temp=list;
	ComplexList *node=list;
	for(int i=0;node&&i<2;i++)
		node=node->pNext;
	while(node)
	{
		temp->pOther=node;
		temp=temp->pNext;
		node=node->pNext;
	}
}

//第一步:复制结点;
void CloneNode(ComplexList *head)
{
	ComplexList *pNode=head;
	while(pNode!=NULL)
	{
		ComplexList *pClone=new ComplexList;
		pClone->data=pNode->data;
		pClone->pNext=pNode->pNext;
		pClone->pOther=NULL;
		
		pNode->pNext=pClone;
		pNode=pClone->pNext;
	}
}
//第二步:复制任意指针;
void ConnectpOtherNode(ComplexList *head)
{
	ComplexList *node=head;
	while(NULL==node)
	{
		ComplexList *pClone=node->pNext;
		if(node->pOther!=NULL)
			pClone->pOther=node->pOther->pNext;
		node=pClone->pNext;
	}
}
//第三步:拆分链表;
ComplexList *SlipList(ComplexList *head)
{
	ComplexList *node=head;
	ComplexList *pCloneHead=NULL;
	ComplexList *pClonenode=NULL;
	if(node!=NULL)
	{
		pCloneHead=pClonenode=node->pNext;
		node->pNext=pClonenode->pNext;
		node=node->pNext;
	}
	while(node)
	{
		pClonenode->pNext=node->pNext;
		pClonenode=node->pNext;
		node->pNext=pClonenode->pNext;
		node=pClonenode->pNext;
	}
	return pCloneHead;
}
//第四步:返回新的复杂链表的头结点:
ComplexList *GetNewCopyHead(ComplexList *pHead)
{
	CloneNode(pHead);
	ConnectpOtherNode(pHead);
	return SlipList(pHead);
}
int main()
{
	CreateList(&pHead,arr,5);
	Set_pOther(pHead);
	ComplexList *p=pHead;
	cout<<"任意指针指向的值:";
	for(int i=0;i<3;++i)
	{
		cout<<p->pOther->data<<" ";
		p=p->pNext;
	}
	cout<<endl<<"原复杂链表的值:";
	show(pHead);
	cout<<"复制的新复杂链表的值:";
	show(GetNewCopyHead(pHead));
	system("pause");
	return 0;
}

运行结果:




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值