您的位置:首页 > Web前端

剑指Offer26复杂链表的复制

2014-08-27 10:21 423 查看
题目:

请实现函数复制一个复杂链表,在复杂链表中,每个结点除了有一个m_pNext指针指向下一个结点外,还有一个m_pSibling指向链表中的任意结点或者NULL。

分析:

这个题还是挺有难度的,我刚拿到题的时候想的是我可以先把简单链表复制一遍,然后再从头挨着找m_pSibling指针指向的结点,这样一算时间复杂就成了O(n2)了,显然这是最最直接也是最笨的方法,那么肯定会有更好的方法。

这个题我没想出来,后来看到书上是这么介绍的,总共介绍了2种方法,加上上面最笨的方法总共3种,下面我来详细阐述一下。

第一种:

因为在找m_pSibling指针指向结点的过程中是要从头开始遍历的,这样就把时间都浪费在了寻找结点的身上了,那么可以用一种方法来节省寻找结点的时间花费。对了,就是用空间置换时间,可以增加一个数组来记录每个数组中的值对应一个结点,这样当查找结点时就可以直接查找数组,然后对应到结点上就好了。当然这里的数组不是简单的数组,而是一个可以存储结点的表。

第二种:

这是一种没有另外增加空间的方法,很神奇吧!下面我们就来慢慢看这种方法,这种方法是一种让人享受的方法。

我们想在整个问题的解决过程中,最浪费时间的地方就是寻找m_psibling指针指向的结点,我们的优化方法就一直围绕着这一点来进行,前面的思路是用一个外开的内存来记录所对应的位置,那如果我们一开始就知道他的位置是不是就不用再寻找了?!对!是不用再寻找了。可是怎么就能一开始就知道他的位置呢?我们知道的原始链表的位置,那我们能不能在它身上做文章呢?当然可以了,可怎做呢?哈哈!灵机一动!奥!算法!!!

当我们在复制链表的过程中,我们是另外开辟了一个空间来存放的,那么我们如果就在这个链表身上复制呢?对啊!可以把每个结点对应的复制的结点都放在各自结点的后面。



就像图中展示一样。似乎这时候就不用再用语言来表达了,这是算法的神奇。

可以分成三步来实现,

1.复制链表,实现m_pNext指针,并把复制链表和原始链表穿插进行成一个链表,这样奇数位置是原始链表,偶数位置就是复制的链表。

2.实现m_pSibling指针,x结点的m_psibling指针指向y,那么x的下一个结点就是复制的x·结点,它的m_psibling指针就指向y的下一个结点y·

3,分来链表,奇数位置的是原始链表,偶数位置的是复制链表。

下面看代码:

void CloneNodes(ComplexListNode * pHead)
{
ComplexListNode * pNode = pHead;
while(pNode != NULL)
{
ComplexListNode * CloneNode = new ComplexListNode();
CloneNode->m_nValue = pNode->m_nValue;
CloneNode->m_pNext = pNode->m_pNext;
CloneNode->m_pSibling = NULL;

pNode->m_pNext = CloneNode;
pNode = CloneNode->m_pNext;
}
}

void ConnectSiblingNodes(ComplexListNode * pHead)
{
ComplexListNode * pNode = pHead;

while(pNode != NULL)
{
ComplexListNode * pNodeNext = pNode->m_pNext;

if(pNode->m_pSibling != NULL)
pNodeNext->m_pSibling = pNode->m_pSibling->m_pNext;
pNode = pNodeNext->m_pNext;
}
}

ComplexListNode * ReConnectNodes(ComplexListNode * pHead)
{
ComplexListNode * pNode = pHead;
ComplexListNode * CloneHead = NULL;
ComplexListNode * CloneNode = NULL;
if(pNode != NULL)
{
CloneHead = CloneNode = pNode->m_pNext;
pNode->m_pNext = CloneNode->m_pNext;
pNode = pNode->m_pNext;
}
while(pNode != NULL)
{
CloneNode->m_pNext = pNode->m_pNext;
CloneNode = CloneNode->m_pNext;

pNode->m_pNext = CloneNode->m_pNext;
pNode = pNode->m_pNext;
}
return CloneHead;
}
ComplexListNode * Clone(ComplexListNode * pHead)
{

CloneNodes(pHead);
ConnectSiblingNodes(pHead);
ComplexListNode * result = ReConnectNodes(pHead);
return result;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: