/*请实现函数ComplexListNode* Clone(ComplexListNode *pHead),复制一个复制链表,在复杂链表中,
每个结点除了一个m_pNext指针指向下一个节点外,还有一个m_pSibling指向链表中的任意结点或者NULL*/
#include <iostream>
using namespace std;
//复杂链表结点定义
struct ComplexLinkListNode
{
int m_nValue;
ComplexLinkListNode *m_pNext;
ComplexLinkListNode *m_pSibling;
};
//创建链表结点
ComplexLinkListNode *CreateLinkListNode(int ival)
{
ComplexLinkListNode *OneNode = new ComplexLinkListNode();
OneNode -> m_nValue = ival;
OneNode -> m_pNext = NULL;
OneNode -> m_pSibling =NULL;
return OneNode;
}
//连接结点
void ConnectLinkList(ComplexLinkListNode *pNode1, ComplexLinkListNode *pNode2, ComplexLinkListNode *pNode3)
{
pNode1 -> m_pNext = pNode2;
pNode1 -> m_pSibling = pNode3;
}
//释放空间(递归实现,从尾结点开始递归删除结点)
void FreeSpace(ComplexLinkListNode *pHead)
{
if(pHead != NULL)
{
FreeSpace(pHead -> m_pNext);
delete pHead;
}
}
//第一步:复制结点并连接成这样A -> A' -> B -> B' ...
void CloneNodes(ComplexLinkListNode *pHead)
{
ComplexLinkListNode *pNode = pHead;
while(pNode != NULL)
{
//动态分配空间创建一个复制结点
ComplexLinkListNode *pCloned = new ComplexLinkListNode();
//复制头结点值,指针
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(ComplexLinkListNode *pHead)
{
ComplexLinkListNode *pNode = pHead;
while(pNode != NULL)
{
ComplexLinkListNode *pCloned = pNode -> m_pNext;
if(pNode -> m_pSibling != NULL)
{
pCloned -> m_pSibling = pNode -> m_pSibling -> m_pNext;
}
pNode = pCloned -> m_pNext;
}
}
//第三步:拆分链表 -> 奇数位置上的点组成原链表,偶数位置上的点组成复制出来的链表
ComplexLinkListNode *ReconnectNodes(ComplexLinkListNode *pHead)
{
//创建指向原链表结点的指针,并赋头结点的初值
ComplexLinkListNode *pNode = pHead;
//创建指向复制链表头结点的指针
ComplexLinkListNode *pClonedHead = NULL;
//创建指向复制链表结点的指针
ComplexLinkListNode *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;
}
//第四步:封装以上三步
ComplexLinkListNode *Clone(ComplexLinkListNode *pHead)
{
CloneNodes(pHead);
ConnectSiblingNodes(pHead);
return ReconnectNodes(pHead);
}
//输出链表
void PrintLinklist(ComplexLinkListNode *pHead)
{
if(pHead == NULL)
return;
while(pHead != NULL)
{
cout << pHead -> m_nValue << " ";
pHead = pHead -> m_pNext;
}
cout << endl;
}
//=======测试代码======
void Test(char *TestName, ComplexLinkListNode *pHead)
{
if(TestName != NULL)
cout << TestName << " Begins: " << endl;
cout << "The original Linklist is: " << endl;
PrintLinklist(pHead);
ComplexLinkListNode *pClonedHead = Clone(pHead);
cout << "The cloned Linklist is: " << endl;
PrintLinklist(pClonedHead);
FreeSpace(pHead);
FreeSpace(pClonedHead);
}
//=======测试用例======
// -----------------
// \|/ |
// 1-------2-------3-------4-------5
// | | /|\ /|\
// --------+-------- |
// -------------------------
void Test1()
{
ComplexLinkListNode *pNode1 = CreateLinkListNode(1);
ComplexLinkListNode *pNode2 = CreateLinkListNode(2);
ComplexLinkListNode *pNode3 = CreateLinkListNode(3);
ComplexLinkListNode *pNode4 = CreateLinkListNode(4);
ComplexLinkListNode *pNode5 = CreateLinkListNode(5);
ConnectLinkList(pNode1, pNode2, pNode3);
ConnectLinkList(pNode2, pNode3, pNode5);
ConnectLinkList(pNode3, pNode4, NULL);
ConnectLinkList(pNode4, pNode5, pNode2);
Test("Test1", pNode1);
}
// m_pSibling指向结点自身
// -----------------
// \|/ |
// 1-------2-------3-------4-------5
// | | /|\ /|\
// | | -- |
// |------------------------|
void Test2()
{
ComplexLinkListNode *pNode1 = CreateLinkListNode(1);
ComplexLinkListNode *pNode2 = CreateLinkListNode(2);
ComplexLinkListNode *pNode3 = CreateLinkListNode(3);
ComplexLinkListNode *pNode4 = CreateLinkListNode(4);
ComplexLinkListNode *pNode5 = CreateLinkListNode(5);
ConnectLinkList(pNode1, pNode2, NULL);
ConnectLinkList(pNode2, pNode3, pNode5);
ConnectLinkList(pNode3, pNode4, pNode3);
ConnectLinkList(pNode4, pNode5, pNode2);
Test("Test2", pNode1);
}
// m_pSibling形成环
// -----------------
// \|/ |
// 1-------2-------3-------4-------5
// | /|\
// | |
// |---------------|
void Test3()
{
ComplexLinkListNode *pNode1 = CreateLinkListNode(1);
ComplexLinkListNode *pNode2 = CreateLinkListNode(2);
ComplexLinkListNode *pNode3 = CreateLinkListNode(3);
ComplexLinkListNode *pNode4 = CreateLinkListNode(4);
ComplexLinkListNode *pNode5 = CreateLinkListNode(5);
ConnectLinkList(pNode1, pNode2, NULL);
ConnectLinkList(pNode2, pNode3, pNode5);
ConnectLinkList(pNode3, pNode4, NULL);
ConnectLinkList(pNode4, pNode5, pNode2);
Test("Test3", pNode1);
}
//只有一个结点
void Test4()
{
ComplexLinkListNode *pNode1 = CreateLinkListNode(1);
ConnectLinkList(pNode1, NULL, pNode1);// ConnectLinkList(pNode1, pNode1, NULL)是不同的,
//这个函数会循环输出
Test("Test4", pNode1);
}
//输入为空指针的鲁棒性测试
void Test5()
{
Test("Test5", NULL);
}
int main()
{
Test1();
cout << endl;
Test2();
cout << endl;
Test3();
cout << endl;
Test4();
cout << endl;
Test5();
return 0;
}
/*把复杂链表的复制过程分解成三个步骤,同时把每个步骤都用图形化的方式表示出来,写代码的时候为每一个步骤
定义一个子函数,最后在复制函数中先后调用这三个函数*/
面试题26:复杂链表的复制
最新推荐文章于 2023-12-17 00:15:00 发布