(本博客旨在个人总结回顾)
题目描述:
请实现函数ComplexListNode* Clone(ComplexListNode* pHead),复制一个复杂链表。在复杂链表中,每个结点除了有一个m_pNext指针指向下一个结点外,还有一个m_pSibling指向链表中的任意结点或者NULL.
结点的C++定义如下:
struct ComplexListNode
{
int m_nValue;
ComplexListNode* m_pNext;
ComplexListNode* m_pSibling;
};
解题思路:
解法一:
使用分治法处理题目:①先简单拷贝链表,并存储链表各个结点及其对应的各个拷贝结点。②将简单拷贝的链表每个结点m_pSibling指向其对应拷贝的结点。
此方法时间复杂度为O(n),并且需要辅助空间。可使用map映射存储原结点及其拷贝结点。
完整代码:
#include "stdafx.h"
#include <iostream>
#include <map>
using namespace std;
struct ComplexListNode
{
int m_nValue;
ComplexListNode* m_pNext;
ComplexListNode* m_pSibling;
};
/*
* @name InsertListForEachNode
* @brief 在链表每个结点之后插入每个结点的拷贝
* @param [in] ComplexListNode * pHead
* @return void
*/
void InsertListForEachNode(ComplexListNode* pHead)
{
if (pHead != NULL)
{
ComplexListNode* pNext = NULL;
ComplexListNode* pTmp = NULL;
while (pHead != NULL)
{
pNext = pHead->m_pNext;
//简单拷贝结点并插入
pTmp = new ComplexListNode();
pTmp->m_nValue = pHead->m_nValue;
pTmp->m_pSibling = pHead->m_pSibling;
pTmp->m_pNext = pNext;
pHead->m_pNext = pTmp;
pHead = pNext;
}
}
}
/*
* @name GetResultList
* @brief 将插入后的链表m_bSibling指向下一个位置,并分离出目标链表
* @param [in] ComplexListNode * pHead
* @return ComplexListNode* 分离出拷贝的链表
*/
ComplexListNode* GetResultList(ComplexListNode* pHead)
{
ComplexListNode* pResult = NULL;
if (NULL != pHead)
{
ComplexListNode* pResultIndex = NULL;
ComplexListNode* pNext = NULL;
bool bCloneNode = false;
while (NULL != pHead)
{
pNext = pHead->m_pNext;
if (bCloneNode)
{
if (NULL != pHead->m_pSibling)
{
pHead->m_pSibling = pHead->m_pSibling->m_pNext;
}
if (NULL == pResultIndex)
{
pResultIndex = pHead;
pResult = pResultIndex;
}
else
{
pResultIndex->m_pNext = pHead;
pResultIndex = pResultIndex->m_pNext;
}
}
else
{
if (pHead->m_pNext != NULL)
{
pHead->m_pNext = pHead->m_pNext->m_pNext;
}
}
bCloneNode = !bCloneNode;
pHead = pNext;
}
}
return pResult;
}
/*
* @name Clone
* @brief 复杂链表的复制
* @param [in] ComplexListNode* pHead
* @return ComplexListNode* 返回复制链表的头结点
*/
ComplexListNode* Clone(ComplexListNode* pHead)
{
ComplexListNode* pHeadResult = NULL;
if (pHead != NULL)
{
InsertListForEachNode(pHead);
pHeadResult = GetResultList(pHead);
}
return pHeadResult;
}
int _tmain(int argc, _TCHAR* argv[])
{
// ____________________
// | |
// V |
// A-------->B-------->C-------->D-------->E
// | | /\ /\
// |_________|_________| |
// |____________________________|
ComplexListNode* pA = new ComplexListNode();
pA->m_nValue = 10;
ComplexListNode* pB = new ComplexListNode();
pA->m_pNext = pB;
pB->m_nValue = 20;
ComplexListNode* pC = new ComplexListNode();
pB->m_pNext = pC;
pC->m_nValue = 30;
ComplexListNode* pD = new ComplexListNode();
pC->m_pNext = pD;
pD->m_nValue = 40;
ComplexListNode* pE = new ComplexListNode();
pD->m_pNext = pE;
pE->m_nValue = 50;
pA->m_pSibling = pC;
pB->m_pSibling = pE;
pD->m_pSibling = pB;
ComplexListNode* pA1 = Clone(pA);
Clone(NULL);
Clone(new ComplexListNode());
system("pause");
return 0;
}
解法二:
①原链表:实线表示m_pNext,虚线表示m_pSibling,指向NULL不使用线表示。
②在原链表中每一个结点后插入该结点的拷贝结点。
③拷贝结点m_pSibing指向原结点(前一结点)的m_pSibing的下一个结点
④将原结点和拷贝结点分开成原链表和拷贝链表:
完整代码:
#include "stdafx.h"
#include <iostream>
#include <map>
using namespace std;
struct ComplexListNode
{
int m_nValue;
ComplexListNode* m_pNext;
ComplexListNode* m_pSibling;
};
/*
* @name InsertListForEachNode
* @brief 在链表每个结点之后插入每个结点的拷贝
* @param [in] ComplexListNode * pHead
* @return void
*/
void InsertListForEachNode(ComplexListNode* pHead)
{
if (pHead != NULL)
{
ComplexListNode* pNext = NULL;
ComplexListNode* pTmp = NULL;
while (pHead != NULL)
{
pNext = pHead->m_pNext;
//简单拷贝结点并插入
pTmp = new ComplexListNode();
pTmp->m_nValue = pHead->m_nValue;
pTmp->m_pSibling = pHead->m_pSibling;
pTmp->m_pNext = pNext;
pHead->m_pNext = pTmp;
pHead = pNext;
}
}
}
/*
* @name GetResultList
* @brief 将插入后的链表m_bSibling指向下一个位置,并分离出目标链表
* @param [in] ComplexListNode * pHead
* @return ComplexListNode* 分离出拷贝的链表
*/
ComplexListNode* GetResultList(ComplexListNode* pHead)
{
ComplexListNode* pResult = NULL;
if (NULL != pHead)
{
ComplexListNode* pResultIndex = NULL;
bool bCloneNode = false;
while (NULL != pHead)
{
if (bCloneNode)
{
if (NULL != pHead->m_pSibling)
{
pHead->m_pSibling = pHead->m_pSibling->m_pNext;
}
if (NULL == pResultIndex)
{
pResultIndex = pHead;
pResult = pResultIndex;
}
else
{
pResultIndex->m_pNext = pHead;
pResultIndex = pResultIndex->m_pNext;
}
}
bCloneNode = !bCloneNode;
pHead = pHead->m_pNext;
}
}
return pResult;
}
/*
* @name Clone
* @brief 复杂链表的复制
* @param [in] ComplexListNode* pHead
* @return ComplexListNode* 返回复制链表的头结点
*/
ComplexListNode* Clone(ComplexListNode* pHead)
{
ComplexListNode* pHeadResult = NULL;
if (pHead != NULL)
{
InsertListForEachNode(pHead);
pHeadResult = GetResultList(pHead);
}
return pHeadResult;
}
int _tmain(int argc, _TCHAR* argv[])
{
// ____________________
// | |
// V |
// A-------->B-------->C-------->D-------->E
// | | /\ /\
// |_________|_________| |
// |____________________________|
ComplexListNode* pA = new ComplexListNode();
pA->m_nValue = 10;
ComplexListNode* pB = new ComplexListNode();
pA->m_pNext = pB;
pB->m_nValue = 20;
ComplexListNode* pC = new ComplexListNode();
pB->m_pNext = pC;
pC->m_nValue = 30;
ComplexListNode* pD = new ComplexListNode();
pC->m_pNext = pD;
pD->m_nValue = 40;
ComplexListNode* pE = new ComplexListNode();
pD->m_pNext = pE;
pE->m_nValue = 50;
pA->m_pSibling = pC;
pB->m_pSibling = pE;
pD->m_pSibling = pB;
ComplexListNode* pA1 = Clone(pA);
Clone(NULL);
Clone(new ComplexListNode());
system("pause");
return 0;
}