複雜鏈表節點結構:
struct ComplexNode
{
ComplexNode(const int& d)
:_data(d)
,_next(NULL)
,random(NULL)
{}
int _data; //數據域
ComplexNode* _next; //指向下一節點
ComplexNode* _random; //指向隨機節點
};
複製複雜鏈表可以分爲三步來完成:
第一步:將新複製的節點插入到原來鏈表當中(插入到原節點後面)
圖示:
代碼實現:
void CloneNodes(ComplexNode* pHead)
{
ComplexNode* cur = pHead;
while(cur)
{
ComplexNode* NewHead = new ComplexNode(); //開闢新節點
NewHead->_data = cur->_data;
NewHead->_next = cur->_next;
NewHead->_random = NULL;
cur->_next = NewHead; //連接新節點
cur = NewHead->_next; //跳轉到下一個要複製的節點
}
}
第二步:修改新開闢的節點的_random,新的_random其實就是舊的_random的_next(新開闢的節點鏈在原來節點的後面,所以就是舊的_random->_next)
代碼實現:
void UpdateNewNodeRandom(ComplexNode* pHead)
{
ComplexNode* cur = pHead;
while(cur)
{
ComplexNode* next = cur->_next; //指向新節點
if(cur->_random != NULL) //優化:隨機指針不爲空時,複製
{
next->_random = cur->_random->_next; //複製隨機指針
}
cur = next->_next; //下一個要複製的節點
}
}
第三步:將複製出來的鏈表拆分出來
代碼實現:
ComplexNode* DisconnectNewNode(ComplexNode* pHead)
{
ComplexNode* cur = pHead; //指向原來的節點
ComplexNode* next = NULL; //指向複製出來的節點
ComplexNode* pNewHead = NULL; //新鏈表的頭節點
if(cur != NULL)
{
pNewHead = next = cur->_next; //指向新鏈表的頭
cur->_next = next->_next; //將新節點分離
cur = next->_next;
}
while(cur)
{
next->_next = cur->_next; //往複製出的鏈表上面連接新節點
next = next->_next; //分離新節點
cur->_next = next->_next;
cur = next->_next;
}
return pNewHead; //返回新鏈表的頭結點
}
最後複製複雜鏈表就轉化下面代碼:
ComplexNode<T>* CopyComplexLinkList(ComplexNode<T>* pHead)
{
if(pHead != NULL) //判空
{
CloneNodes<T>(pHead); //複製節點並連接在其後面
UpdateNewNodeRandom(pHead); //更新新節點的隨機指針
return DisconnectNewNode<T>(pHead);/ /拆分鏈表並返回新鏈表的頭結點
}
return NULL;
}
創建複雜鏈表:
ComplexNode* CreatList()
{
ComplexNode* Node1 = new ComplexNode(1); //創建節點
ComplexNode* Node2 = new ComplexNode(2);
ComplexNode* Node3 = new ComplexNode(3);
ComplexNode* Node4 = new ComplexNode(4);
ComplexNode* Node5 = new ComplexNode(5);
Node1->_next = Node2; //連接節點
Node2->_next = Node3;
Node3->_next = Node4;
Node4->_next = Node5;
Node1->_random = Node3; //置_random
Node2->_random = Node4;
Node3->_random = Node1;
Node4->_random = Node5;
Node5->_random = Node2;
return Node1; //返回頭
}
打印鏈表:
void Print(ComplexNode* _head)
{
ComplexNode* cur = _head;
while(cur)
{
cout<<"("<<cur->_data<<","<<cur->_random->_data<<")"<<"->";
cur = cur->_next;
}
cout<<"Nvl."<<endl;
}
測試代碼:
void Test()
{
ComplexNode* head = CreatList();
Print(head);
cout<<"---------------------------------------"<<endl;
ComplexNode* NewHead = CopyList(head);
Print(NewHead);
}
測試結果:
總結:複雜鏈表的複製分爲三步:第一步就是把新複製出來的節點插入源鏈表中,第二步修改新插入節點的隨機指針,第三步就是將新節點從源中拆分出來,並合併成一個新鏈表。
本文出自 “Pzd流川楓” 博客,請務必保留此出處http://xujiafan.blog.51cto.com/10778767/1766972