复制一个复杂链表,在复杂链表中,每个节点除了有个m_next指针外,还有一个m_psibing指针,它指向链表中的任意节点或者为NULL。

这个问题给人第一印象挺难的,不过,我们可以分成几步就可以将它搞定:

(一)复制原始链表的每一个节点N,并且把新节点连接到旧节点的后边

wKiom1cQrULj6w9XAAAiHWP_QJA197.png

(二)设置复制出来的新节点的m_psibing,假设原来链表上的N的m_psibing指向节点s,则复制出来的节点指向m_psibing->m_next

wKioL1cQr4zDTQDHAAAlCByFUd0839.png

(三)把长链表拆分成两个相等的短链表

wKiom1cQr1CCl7lIAAAeYweaqpY790.png

源代码如下:

#include<iostream>
#include<assert.h>
using namespace std;

struct Node
{
	Node * m_next;
	Node * m_psibing;
	int value;
};
//1复制原始链表上的任意节点N,再把复制好的节点连在原来节点的后边
void CloneNodes( Node* pHead)
{
	assert(pHead);
	Node* cur=pHead;
	while(cur!=NULL)
	{
	   Node* pclone=new Node();
	   pclone->value=cur->value;
	   pclone->m_next=cur->m_next;
	   pclone->m_psibing=NULL;
	   cur->m_next=pclone;
	   cur=pclone->m_next;

	}
}
//2如果原始链表的m_psibing,指向L,则复制后的节点也指向L
void ClonePsibingNode(Node* pHead)
{
  assert(pHead);
  Node* cur=pHead;
  while(cur!=NULL)
  {
    Node* pclone=cur->m_next;
	while(cur->m_psibing !=NULL)
	{
	pclone->m_psibing =cur->m_psibing->m_next;
	}
	cur=pclone->m_next ;
  }
}
//3拆分链表,把刚才复制好的链表拆分成两个即可达到复制的效果
Node* ReconnectNodes(Node* pHead)
{
	assert(pHead);
	Node* cur=pHead;
	Node*pcloneHead=cur->m_next ;
	Node* pclone=cur->m_next ;
	cur->m_next =pclone->m_next;
	cur=cur->m_next ;
	while(cur!=NULL)
	{
	 pclone->m_next =cur->m_next ;
	 pclone=pclone->m_next;
	 cur->m_next =pclone->m_next ;
	 cur=cur->m_next ;
	}
  return pcloneHead;
}
//主函数
Node * Clone(Node* pHead)
{
	assert(pHead);
	CloneNodes(pHead);
	ClonePsibingNode(pHead);

	return ReconnectNodes(pHead);
}
int main()
{

	Node* p1=new Node();
	Node* p2=new Node();
	Node* p3=new Node();
	Node* p4=new Node();
	p1->m_next =p2;
	p2->m_next =p3;
	p3->m_next =p4;
	p4->m_next =NULL;

	p1->value =1;
	p2->value =2;
	p1->value =3;
	p2->value =4;

	p1->m_psibing=p3;
	p4->m_psibing=p2;
	p2->m_psibing =NULL;
	p3->m_psibing =NULL;

	Node*pcloneHead=Clone(p1);
	cout<<pcloneHead<<endl;
	getchar();
	return 0;
}