1.给定一个复杂的链表的数据结构,复制这个链表,在这个数据结构中,每个节点有两个指针,一个指针指向下一个结点,另一个指针指向链表中的任意结点。




结果:

数据结构:
struct ComplexListNode
{
int m_nValue;
ComplexListNode* m_pNext;
ComplexListNode* m_pSibling;//随机指针
};分析:
如下图所示是一个复杂链表的示意图,实现标志指向下一节点的指针,虚线表示指向任意结点的m_pSibling指针。如果m_pSibling为空的话,则并没有指出。
第一步:根据原始链表的每个结点在对应的位置后面复制一个节点N‘ ,如下:
第二步:将复制的节点部分的随机指针按照原始链表的对应关系连接起来
第三步:将整个长的链表拆分成两个链表,奇数位置的节点为复制的结点,偶数位置的接点是原始的结点。整个时间复杂度是O(n)。
源码:
#include<iostream>
using namespace std;
//复杂链表结构
struct ComplexListNode
{
int m_nValue;
ComplexListNode* m_pNext;
ComplexListNode* m_pSibling;//随机指针
};
//创建结点
ComplexListNode* CreateNode(int nValue);
//链接结点
void BuildNodes(ComplexListNode* pNode, ComplexListNode* pNext, ComplexListNode* pSibling);
//打印链表
void PrintList(ComplexListNode* pHead);
//复制结点并插入
void CloneNodes(ComplexListNode* pHead);
//链接复制结点的随机指针
void ConnectSiblingNodes(ComplexListNode* pHead);
//断开重连接
ComplexListNode* ReconnectNodes(ComplexListNode* pHead);
ComplexListNode* Clone(ComplexListNode* pHead);
int main()
{
// -----------------
// \|/ |
// 1-------2-------3-------4-------5
// | | /|\ /|\
// --------+-------- |
// -------------------------
ComplexListNode* pNode1 = CreateNode(1);
ComplexListNode* pNode2 = CreateNode(2);
ComplexListNode* pNode3 = CreateNode(3);
ComplexListNode* pNode4 = CreateNode(4);
ComplexListNode* pNode5 = CreateNode(5);
BuildNodes(pNode1, pNode2, pNode3);
BuildNodes(pNode2, pNode3, pNode5);
BuildNodes(pNode3, pNode4, NULL);
BuildNodes(pNode4, pNode5, pNode2);
printf("The original list is:\n");
PrintList(pNode1);
ComplexListNode* pClonedHead = Clone(pNode1);
printf("The cloned list is:\n");
PrintList(pClonedHead);
system("PAUSE");
return 0;
}
//创建结点
ComplexListNode* CreateNode(int nValue)
{
ComplexListNode* pNode = new ComplexListNode();
pNode->m_nValue = nValue;
pNode->m_pNext = NULL;
pNode->m_pSibling = NULL;
return pNode;
}
//连接结点
void BuildNodes(ComplexListNode* pNode, ComplexListNode* pNext, ComplexListNode* pSibling)
{
if(pNode != NULL)
{
pNode->m_pNext = pNext;
pNode->m_pSibling = pSibling;
}
}
//打印
void PrintList(ComplexListNode* pHead)
{
ComplexListNode* pNode = pHead;
while(pNode != NULL)
{
printf("The value of this node is: %d.\n", pNode->m_nValue);
if(pNode->m_pSibling != NULL)
printf("The value of its sibling is: %d.\n", pNode->m_pSibling->m_nValue);
else
printf("This node does not have a sibling.\n");
printf("\n");
pNode = pNode->m_pNext;
}
}
//复制链表
ComplexListNode* Clone(ComplexListNode* pHead)
{
CloneNodes(pHead);
ConnectSiblingNodes(pHead);
return ReconnectNodes(pHead);
}
//复制原结点并插入
void CloneNodes(ComplexListNode* pHead)
{
ComplexListNode* pNode = pHead;
while(pNode != NULL)
{
ComplexListNode* pCloned = new ComplexListNode();
pCloned->m_nValue = pNode->m_nValue;
pCloned->m_pNext = pNode->m_pNext;
pCloned->m_pSibling = NULL;
pNode->m_pNext = pCloned;
pNode = pCloned->m_pNext;
}
}
//连接复制结点的随机指针
void ConnectSiblingNodes(ComplexListNode* pHead)
{
ComplexListNode* pNode = pHead;
while(pNode != NULL)
{
ComplexListNode* pCloned = pNode->m_pNext;
if(pNode->m_pSibling != NULL)
{
pCloned->m_pSibling = pNode->m_pSibling->m_pNext;
}
pNode = pCloned->m_pNext;
}
}
//重新断开连接
ComplexListNode* ReconnectNodes(ComplexListNode* pHead)
{
ComplexListNode* pNode = pHead;
ComplexListNode* pClonedHead = NULL;
ComplexListNode* pClonedNode = NULL;
if(pNode != NULL)
{
pClonedHead = pClonedNode = pNode->m_pNext;
pNode->m_pNext = pClonedNode->m_pNext;
pNode = pNode->m_pNext;
}
while(pNode != NULL)
{
pClonedNode->m_pNext = pNode->m_pNext;
pClonedNode = pClonedNode->m_pNext;
pNode->m_pNext = pClonedNode->m_pNext;
pNode = pNode->m_pNext;
}
return pClonedHead;
}
本文介绍了如何复制一个复杂链表,该链表中的每个节点包含一个指向下一个节点的指针和一个随机指针,可以指向链表中的任意节点。复制过程分为三步:创建副本节点、连接副本节点的随机指针、断开并重新连接节点,实现时间复杂度为O(n)。并通过示例代码展示了具体实现。
986

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



