##什么是复杂链表?
展示一下复杂链表的结构体样式。
typedef struct ComplexNode
{
struct ComplexNode *next;
struct ComplexNode *random; //指向一个随机值
int data;
}ComplexNode;
复杂链表就是一个带着random指针的单链表。由于random指向的不确定性。让复杂链表的操作存在一定的困难。
假定现在有一个复杂链表的形状如下图:
首先我得思路是创建一个新的链表,依次复制每个节点,但是问题出现了,random指向一个随机值,这个随机值可能没有创建呢,所以依次复制会出现错误。 random的复制成了难题。
所以常规方法行不通,有时候一条路走到黑就真的黑了。
##解题思路
1.首先我们在每个链表节点的后面创建一个新的节点,将其串联起来。如下图的黄色箭头所示。
如图所示:
2.接下来,我们将它的新节点的random指向该指的地方,如下图的绿色箭头所示。
如图所示:
3.接下来我们把两个混在一起的链表拆开,拆开就可以变成两个链表。
如图所示:
##用C语言实现上述操作过程
ComplexNode* Copy(ComplexNode **List)
{
//在每个链表节点后面加一个节点。
ComplexNode *cur = *List;
ComplexNode *NewNode = NULL;
ComplexNode *Next = NULL;
ComplexNode *NewNodeNext = NULL;
ComplexNode *NewList = NULL;
while (cur != NULL) //通过循环在原始链表的基础上创建新的链表,并且挂载在后面。
{
NewNode = CreateNode(cur->data); //createnode函数是创建一个新的节点
NewNode->next = cur->next;
cur->next = NewNode;
cur = NewNode->next;
}
//改变链表的随机指针域的结构
cur = *List;
while (cur != NULL)
{
if (cur->random != NULL) //这个只要random的值不是null就需要找到 对应的newnode的random的位置。
{
NewNode = cur->next;
NewNode->random = cur->random->next;
}
cur = cur->next->next; //依次条两个节点相当于在原链表上移动一个
}
//将新旧两个链表拆开
cur = *List;
NewList = cur->next;
//cur修正的是原链表,NewList修正的是新链表
while (cur != NULL)
{
NewNode = cur->next;
Next = cur->next->next;
if (Next == NULL) //当Next为空时,说明链表的修正快要结束了。
{
NewNodeNext = NULL;
}
else
{
NewNodeNext = Next->next;
}
cur->next = Next;
NewNode->next = NewNodeNext;
cur = Next;
}
return NewList;
}