复杂链表的复制(C语言)

##什么是复杂链表?

展示一下复杂链表的结构体样式。

typedef struct ComplexNode
{
	struct ComplexNode *next;
	struct ComplexNode *random; //指向一个随机值
	int data;
}ComplexNode;

复杂链表就是一个带着random指针的单链表。由于random指向的不确定性。让复杂链表的操作存在一定的困难。

假定现在有一个复杂链表的形状如下图:

复杂链表的复制(C语言)_第1张图片

首先我得思路是创建一个新的链表,依次复制每个节点,但是问题出现了,random指向一个随机值,这个随机值可能没有创建呢,所以依次复制会出现错误。 random的复制成了难题。

所以常规方法行不通,有时候一条路走到黑就真的黑了。

##解题思路

1.首先我们在每个链表节点的后面创建一个新的节点,将其串联起来。如下图的黄色箭头所示。
如图所示:

复杂链表的复制(C语言)_第2张图片

2.接下来,我们将它的新节点的random指向该指的地方,如下图的绿色箭头所示。
如图所示:
复杂链表的复制(C语言)_第3张图片

3.接下来我们把两个混在一起的链表拆开,拆开就可以变成两个链表。
如图所示:

复杂链表的复制(C语言)_第4张图片

##用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;
}

你可能感兴趣的:(数据结构)