本文参考:http://zhedahht.blog.163.com/blog/static/254111742010819104710337/
题目:有一个复杂链表,其结点除了有一个m_pNext指针指向下一个结点外,还有一个m_pSibling指向链表中的任一结点或者NULL。其结点的C++定义如下:
struct ComplexNode
{
int m_nValue;
ComplexNode* m_pNext;
ComplexNode* m_pSibling;
};
下图是一个含有5个结点的该类型复杂链表。图中实线箭头表示m_pNext指针,虚线箭头表示m_pSibling指针。为简单起见,指向NULL的指针没有画出。

方法一:最基本的思路就是先不考虑m_pSibling指针项,将原链表复制。对于m_pSibling,由于新旧链表中结点位置关系是对应的,根据原链表中结点的m_pSibling所指结点在原链表中的位置序号,就可以确定新链表中对应结点的m_pSibling所指的结点。
ComplexNode*Clone(ComplexNode* pHead)
{
ComplexNode *pNewHead,*pNewTempTail,*pCurrent,*pNewCurrent;
pNewHead=pNewTempTail=NULL;
//复制链表,暂不处理m_pSibling项
for(pCurrent=pHead;pCurrent!=NULL;pCurrent=pCurrent->m_pNext)
{
ComplexNode * pTemp=newComplexNode;
pTemp->m_nValue=pCurrent->m_nValue;
pTemp->m_pNext=NULL;
pTemp->m_pSibling=NULL;
if(pNewHead==NULL)
{
pNewHead=pTemp;
pNewTempTail=pTemp;
}
else
{
pNewTempTail->m_pNext=pTemp;
pNewTempTail=pTemp;
}
}
/*对新链表中每个结点pNewCurrent,求原链表中对应位置结点pCurrent的
m_pSibling所直接点的位置index, 然后在新链表中找到第index个结点,
让当pNewCurrent的m_pSibling指向它。*/
pCurrent=pHead,pNewCurrent=pNewHead;
while(pCurrent!=NULL)
{
if(pCurrent->m_pSibling==NULL)
{pCurrent=pCurrent->m_pNext;
continue;}
int index=0; ComplexNode * pTemp; //找pCurrent->m_pSibling在链表中的位置
for(pTemp=pHead;pCurrent->m_pSibling!=pTemp;pTemp=pTemp->m_pNext)
index++; //找到新链表中对应位置的结点
for(pTemp=pNewHead;index!=0;pTemp=pTemp->m_pNext)
index--; //赋值给 pNewCurrent的m_pSibling
pNewCurrent->m_pSibling=pTemp; //处理下一个结点
pCurrent=pCurrent->m_pNext;
pNewCurrent=pNewCurrent->m_pNext;
}
return pNewHead;
}
时间复杂度O(n2),空间复杂度O(1)。
方法二:前面的方法在匹配对应点的时候根据序号来对应,花了较多的时间。这一步可以使用O(n)的辅助空间来提高效率。保存结点的地址对应关系,<p0,p0'>,<p1,p1'>,...p0,p1等是原链表中各结点的地址,p0',p1'等是新链表中各结点的地址。使用hash表,hash(p0)=p0',hash(p1)=p1'。。。
方法三:参考文章中的巧妙解法,是直接在原链表中保存结点的对应关系,即暂时把复制的结点插在原结点后面,等把m_pSibling项处理完后再把链表分离。步骤如图所示:第一步,CloneNodes:
第二步,LinkNewNodeSibling:
第三步,SeprateNewFromOld:
//Clone every node of the original list,and insert the new node after it.
void CloneNodes(ComplexNode* pHead)
{
ComplexNode *pCurrent;
pCurrent=pHead;
while(pCurrent!=NULL)
{
ComplexNode *pTemp=new ComplexNode;
pTemp->m_nValue=pCurrent->m_nValue;
pTemp->m_pNext=pCurrent->m_pNext;
pTemp->m_pSibling=NULL;
pCurrent->m_pNext=pTemp;
pCurrent=pTemp->m_pNext;
}
}
//Link every new node's sibling.
void LinkNewNodeSibling(ComplexNode* pHead)
{
ComplexNode *pCurrent,*pCurrentClone;
for(pCurrent=pHead;pCurrent!=NULL;pCurrent=pCurrent->m_pNext->m_pNext)
{
pCurrentClone=pCurrent->m_pNext;
if(pCurrent->m_pSibling!=NULL)
pCurrentClone->m_pSibling=pCurrent->m_pSibling->m_pNext;
}
}
//Seperate the new list from original list.
ComplexNode* SeparateNewFromOld(ComplexNode* pHead)
{
if(pHead==NULL)
return NULL;
ComplexNode *pNewHead,*pNewTempTail,*pCurrent;
pNewHead=pHead->m_pNext;
pNewTempTail=pNewHead;
for(pCurrent=pHead;pCurrent!=NULL;pCurrent=pCurrent->m_pNext)
{
pNewTempTail->m_pNext=pCurrent->m_pNext;
pCurrent->m_pNext=pCurrent->m_pNext->m_pNext;
pNewTempTail=pNewTempTail->m_pNext;
pNewTempTail->m_pNext=NULL;
}
return pNewHead;
}
//Clone the original list.
ComplexNode* Clone(ComplexNode* pHead)
{
CloneNodes(pHead);
LinkNewNodeSibling(pHead);
return SeparateNewFromOld(pHead);
}时间复杂度O(n),空间复杂度O(1)。

6万+

被折叠的 条评论
为什么被折叠?



