您的位置:首页 > 其它

复杂链表的复制

2011-11-10 20:06 369 查看

精选软件工程师面试题-复杂链表的复制


(2011-02-28 21:06:55)


转载

个复杂链表,其结点除了有一个m_pNext指针指向下一个结点外,还有一个m_pSibling指向链表中的任一结点或者NULL。其结点的C++定义如下:
structComplexNode
{
int m_nValue;
ComplexNode* m_pNext;
ComplexNode* m_pSibling;
};
下图是一个含有5个结点的该类型复杂链表。图中实线箭头表示m_pNext指针,虚线箭头表示m_pSibling指针。为简单起见,指向NULL的指针没有画出。

请完成函数ComplexNode*Clone(ComplexNode* pHead),以复制一个复杂链表。

分析: 此题目已经有很多人在blog上做过分析, 我没有一个比较精练的, 在次我描述出我的想法. 仅供参考.
这个题目的难点在于如何对m_pSibling指针复制,使新的列表具有和原列表同样的结构.
如原列表是ABCDE,Clone列表是abcde.




难点在于:如何复制虚线部分的指针.
[align=left]其实有个很巧妙的方法, 给A,B,C,D,E编号,分别为0,1,2,3,4.如果所示. 这样m_pSibling的clone就很简单.[/align]
[align=left]Forexample:[/align]
[align=left] 节点 b 对应的是原节点B, B->m_pSibling 是E, E的编号是4.这样新列表的第4个节点的地址赋给b->m_pSibling就可以了.[/align]
[align=left]但关键一点是原列表每个节点的编号保存在哪呢?如果编号没有地方保存, 也不能降低clone的复杂度. 我们注意到没每个节电有一个m_nValue成员, 我们可以利用它来做文章.即首先把每个节电的m_nValue备份出来, 临时用来保存编号, 等clone完成后, 再restore.[/align]
[align=left]同时还要把a,b,c.d,e的地址也按顺序保存在一个数组里,以方便获取他们的地址.[/align]
[align=left] [/align]
[align=left]这样这个算法就很简单了,只对原列表遍历两次就可以完成复制, 时间复杂度为O(2n):[/align]

[align=left]备份原列表每个节点的m_nValue 到数组backupValue. 同时分别设置他们为所在节点的序号值.[/align]

[align=left]由原列表 clone出新列表(只设置每个接点的m_pNext值). 新列表每个节点的m_pSibling 置为 NULL.同时新列标的每个节点地址按顺序保留到数组newListAddrees中.[/align]

[align=left]Clone m_pSibling:从原列表取一个节点, 如果此节点的m_pSibling为NULL, 取下一个.假设此节点为M. 由M->m_nValue 找到 m(newListAddrees[M->m_nValue]). 并设置m_pSibling:newListAddrees[M->m_nValue]->m_pSibling=newListAddrees[M->m_pSibling->m_nValue].直到原列表的节点的m_pSibling全复制完.[/align]

[align=left]由backupValue恢复原列表的m_nValue.[/align]

[align=left]设置新列表的m_nValue.[/align]

[align=left]代码: [/align]
ComplexNode* CloneList(ComplexNode* pHead)

{

ComplexNode* pNode = pHead;

ComplexNode** ppBackupNewList;

int nTotal = 0;

int i = 0;

while(pNode)

{

nTotal++;

pNode = pNode->m_pNext;

}
ppBackupNewList = (ComplexNode **)malloc(sizeof(ComplexNode *)*nTotal);

pNode = pHead;

while(pNode != NULL)

{

ppBackupNewList[i] = (ComplexNode *)malloc(sizeof(ComplexNode));

if (i > 0)

ppBackupNewList[i - 1]->m_pNext =ppBackupNewList[i];

ppBackupNewList[i]->m_pSibling = NULL;

ppBackupNewList[i]->m_nValue =pNode->m_nValue;

pNode->m_nValue = i++;

pNode = pNode->m_pNext;

}

ppBackupNewList[nTotal - 1]->m_pNext = NULL;

pNode = pHead;

while(pNode != NULL)

{

if (pNode->m_pSibling)

ppBackupNewList[pNode->m_nValue]->m_pSibling=

ppBackupNewList[pNode->m_pSibling->m_nValue];

pNode = pNode->m_pNext;

}

i = 0;

pNode = pHead;

while(pNode != NULL)

{

pNode->m_nValue =ppBackupNewList[i++]->m_nValue;

pNode = pNode->m_pNext;

}

pNode = ppBackupNewList[0];

free(ppBackupNewList);

return pNode;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: