什么是复杂链表?
复杂链表指的是一个链表有若干个结点,每个结点有一个数据域用于存放数据,还有两个指针域,其中一个指向下一个节点,还有一个随机指向当前复杂链表中的任意一个节点或者是一个空结点。
要实现复制一个复杂链表,首先要知道复杂链表的结构。
复杂链表的数据结构定义如下:
typedef int DataType; //数据域的类型
//复杂链表的数据结构
typedef struct ComplexNode
{
DataType _data ; // 数据
struct ComplexNode * next; // 指向下个节点的指针
struct ComplexNode * random;// 指向随机节点(可以是链表中的任意节点 or 空)
}ComplexNode;
如图1:
图1 复杂链表结点图
然后,确定实现复杂链表复制的步骤:
1、根据已有的复杂链表创建一条新的复杂链表,并且让这个新的复杂链表的所有的结点的random指针都指向空,这样可便于实现。即:相当于我们创建了一条简单的单链表(newlist),见图2,我们要复制的链表不妨称之为oldlist,见图3。
图2 newlist图
图3 oldlist图
2、接下来我们应该把新创建的这条复杂链表(newlist)与已有的复杂链表(oldlist)合并。即:插缝合并,调整next和random指针。
3、再把这一条链表linklist分开成我们的newlist链表和oldlist链表就可以了。
【接口】
#ifndef __COMPLEX__LIST__COPY__H__
#define __COMPLEX__LIST__COPY__H__
//包含头文件
#include <stdio.h>
#include<stdlib.h>
#include <assert.h>
typedef int DataType;//数据域的类型
//复杂链表的数据结构
typedef struct ComplexNode
{
DataType _data; // 数据域
struct ComplexNode * _next; // 指向下个结点的指针
struct ComplexNode * _random;// 指向随机结点(可以是链表中的任意结点或空指针)
}ComplexNode;
//创建一个复杂链表的结点
ComplexNode * BuyComplexNode(DataType x);
//复杂链表的复制
ComplexNode * CopyComplexNode(ComplexNode * cplist);
//打印复杂的单链表
void Display(const ComplexNode * cplist);
#endif//__COMPLEX__LIST__COPY__H__
【功能函数】
#define _CRT_SECURE_NO_WARNINGS 1
#include "ComplexListCopy.h"
//创建一个复杂链表的结点
ComplexNode * BuyComplexNode(DataType x)
{
ComplexNode *cnode = (ComplexNode *)malloc(sizeof(ComplexNode));
if (cnode == NULL)//创建失败
{
perror("BuyComplexNode()::malloc");
return NULL;
}
//创建成功
cnode->_data = x;
cnode->_next = NULL;
cnode->_random = NULL;
return cnode;
}
//打印复杂的单链表
void Display(const ComplexNode * cplist)
{
ComplexNode *pnode = cplist;
while (pnode)
{
printf("%d::%d -->", pnode->_data, pnode->_random->_data);
pnode = pnode->_next;
}
printf("over/n");
}
//复杂链表的复制
ComplexNode * CopyComplexNode(ComplexNode * cplist)
{
ComplexNode * pold = NULL;
ComplexNode * pnew = NULL;
ComplexNode * newlist = NULL;//指向新的复杂链表的头结点的指针
pold = cplist;
//创建一条新的复杂链表
while (pold != NULL)
{
ComplexNode * new_node = BuyComplexNode(pold->_data);
if (newlist == NULL)//当新的复杂链表中没有结点时
{
newlist = new_node;
}
else//当新的复杂链表有结点时
{
ComplexNode * node = newlist;
while (node->_next != NULL)//找到最后一个结点
{
node = node->_next;
}
node->_next = new_node;//插入新的结点
}
pold = pold->_next;
}//创建新的复杂链表结束
//合并两条复杂链表
pold = cplist;
pnew = newlist;
while (pold)
{
ComplexNode * curold = NULL;
ComplexNode * curnew = NULL;
curold = pold->_next;
curnew = pnew->_next;
if (pold->_next == NULL)
{
pold->_next = pnew;
pold = curold;
pnew = curnew;
break;
}
pold->_next = pnew;
pnew->_next = curold;
pold = curold;
pnew = curnew;
}//合并两条复杂链表结束
//让新创建的那条复杂链表上的所有结点的random指针指向相应的结点
pold = cplist;
pnew = newlist;
while (pnew)
{
pnew->_random = pold->_random->_next;
pold = pnew->_next;
if (pold == NULL)//这是pnew的_next指针已经指向空
{
break;
}
pnew = pold->_next;
}//结束
//分离合并后的复杂链表
pold = cplist;
pnew = newlist;
while (pold)
{
ComplexNode * curold = NULL;
ComplexNode * curnew = NULL;
if (pnew->_next == NULL)//已经分离完成
{
pold->_next = NULL;
pnew->_next = NULL;
break;
}
curold = pold->_next->_next;
curnew = pnew->_next->_next;
pold->_next = curold;
pnew->_next = curnew;
pold = curold;
pnew = curnew;
}//分离合并的复杂链表结束
return newlist;
}
【测试函数】
#define _CRT_SECURE_NO_WARNINGS 1
#include "ComplexListCopy.h"
void test()
{
ComplexNode * cplist;
ComplexNode * copylist;
ComplexNode * node1;
ComplexNode * node2;
ComplexNode * node3;
ComplexNode * node4;
cplist = BuyComplexNode(1);
node1 = BuyComplexNode(2);
node2 = BuyComplexNode(3);
node3 = BuyComplexNode(4);
node4 = BuyComplexNode(5);
cplist->_next = node1;
node1->_next = node2;
node2->_next = node3;
node3->_next = node4;
cplist->_random = node3;
node1->_random = node4;
node2->_random = cplist;
node3->_random = node1;
node4->_random = node2;
Display(cplist);
copylist = CopyComplexNode(cplist);
Display(copylist);
}
int main()
{
test();
system("pause");
return 0;
}
【运行结果】
总的说:复杂链表的复制首先要创建新链表,然后插缝合并链表,最后拆分链表。
原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/18215.html