数据结构之复杂链表的复制

1. 什么是复杂链表?

所谓复杂链表,指的是个链表的每个节点,有一个指向next指针指向下一个节点,还有一个random指针指向这个链表中的一个随机节点或者NULL。

什么意思呢?我们来看图说话

如图,每个结点都用next指针指向下一个结点的同时,还用random指针指向任意的结点,注意这里的random指针的指向是随心所欲的,可以指向任何结点(包括NULL)。

2. 怎样复制?

那么我们怎么样对这样的链表进行复制呢?很多人的第一反应是先将每个结点的random指针所指向的信息记录下来,然后再根据记录下的信息进行复制。
这就会有一个问题:既然是复制链表,那么复制得来的链表的每个结点都是新开辟的,有着自己的空间——这个空间一定不是原链表相应结点的空间。我们怎么找到random指针所指向的新空间的地址呢?有一种方法:开辟一个N*N的数组,用来存放原链表每个结点的之间的关系。然而这种方法的时间和空间开销是巨大的。

这里提供一种对复杂链表复制的方案。一共分为三步:
1. 给原链表每个结点后插入值相同的新结点
2. 给新插入结点的随机指针域赋值
3. 将新结点从原来表上重新拆下来

第一步:给原链表每个结点后插入值相同的新结点:

第二步:给新插入结点的随机指针域赋值。以值为1的结点为例,它的结点记为p,由p结点复制过来的结点记为pC。关键代码为:pC->random = p->random->next; 需要注意的一点就是当一个结点的random指针指向NULL时,由该结点复制得来的结点的random指针直接置为NULL。

第三步:将新结点从原来表上重新拆下来。以值为1的结点为例,它的结点记为p,由p结点复制过来的结点记为pC。关键代码为:p->next = pC->next; pC->next = p->next->next;


最终效果为:

假设链表长度为n,那么总的时间复杂度为O(n),空间复杂度为O(1)。

typedef struct PNode{DataType data;struct PNode *next;struct PNode *random;
}*PNode, Node;PNode AddNode(DataType data)        //增加结点
{PNode p = (PNode)malloc(sizeof(Node));if (p != NULL){p->data = data;p->next = NULL;p->random = NULL;return p;}assert(p);return NULL;
}PNode CopyComplexList(PNode pHead)   // 复杂链表复制
{PNode pHead2 = NULL;PNode pNext = NULL; //原链表的当前结点PNode pCur = NULL;  //原链表当前结点的下一个结点if (pHead == NULL){return NULL;}//给原链表每个结点后插入值相同的新结点 pCur = pHead;pNext = pHead->next;    while(pNext){pCur->next = AddNode(pCur->data);   //在当前结点后插入值相同的新结点pCur->next->next = pNext;           //修改新结点的next指针,使其指向原链表当前结点的下一个结点pCur = pNext;                       //移动pCur指针pNext = pNext->next;                //移动pNext指针}pCur->next = AddNode(pCur->data);       //对于最后一个结点,其next为NULL。需单独处理pCur->next->next = pNext;//给新插入结点的随机指针域赋值pCur = pHead;pNext = pHead->next;while(pNext->next)  //复制原链表中前n-1个结点的random指针指向{if (pCur->random == NULL){pNext->random = NULL;}else{pNext->random = pCur->random->next;pCur = pNext->next;pNext = pCur->next;}    }if (pCur->random == NULL)   //对最后一个结点,特殊处理pNext->random = NULL;elsepNext->random = pCur->random->next;//将新结点从原来表上重新拆下来pCur = pHead;pNext = pHead->next;pHead2 = pHead->next;while(pNext->next)  //将原链表中的前n-1个结点拆下来{pCur->next = pNext->next;pNext->next = pCur->next->next;pCur = pCur->next;pNext = pNext->next;}pCur->next = pNext->next;  //最后一个结点特殊处理return pHead2;
}

数据结构之复杂链表复制相关推荐

  1. 数据结构实验之链表五:单链表的拆分-sdut

    数据结构实验之链表五:单链表的拆分 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Problem Description 输入N个 ...

  2. SDUT_2122 数据结构实验之链表七:单链表中重复元素的删除

    提交代码 数据结构实验之链表七:单链表中重复元素的删除 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Discuss Proble ...

  3. SDUT—2054数据结构实验之链表九:双向链表 (基本建立)

    点击打开链接 数据结构实验之链表九:双向链表 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Discuss Problem Des ...

  4. SDUT_2121数据结构实验之链表六:有序链表的建立 (对建立的单项链表结构进行排序)

    点击打开链接 数据结构实验之链表六:有序链表的建立 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Discuss Problem ...

  5. SDUT_2119 数据结构实验之链表四:有序链表的归并

    点击打开链接 数据结构实验之链表四:有序链表的归并 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Discuss Problem ...

  6. SDUT_2118 数据结构实验之链表三:链表的逆置

    点击打开链接 数据结构实验之链表三:链表的逆置 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Discuss Problem De ...

  7. SDUT _2117 数据结构实验之链表二:逆序建立链表

    点击打开链接 数据结构实验之链表二:逆序建立链表 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Discuss Problem D ...

  8. SDUT_2116 数据结构实验之链表一:顺序建立链表

    点击打开链接 数据结构实验之链表一:顺序建立链表 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Discuss Problem D ...

  9. 【手写数据结构】双链表最详细图解

    原创公众号:bigsai 原创不易,如果有收获请不要吝啬你的一键三连! 文章已收录在 全网都在关注的数据结构与算法学习仓库 欢迎star 前言 前面有很详细的讲过线性表(顺序表和链表),当时讲的链表以 ...

最新文章

  1. python下载后如何使用-如何使用Python通过HTTP下载文件
  2. U盘无法安装win10提示Your PC/Device needs to be repaired
  3. vuepress侧边栏配置_VuePress搭建静态博客网站
  4. gSoap客户端调用WebService完成后注意内存释放顺序
  5. paddleOCR常见问题(2)
  6. LBS移动网络基站定位
  7. 项目经理如何才能快速成长?
  8. 目录:所以文章的目录
  9. java获得当前路径_JAVA 取得当前目录的路径/Servlet/class/文件路径/web路径/url地址...
  10. selenium 获取不了标签文本的解决方法
  11. 如何创建删不掉文件夹
  12. 2019AWE海信中央空调发布智慧空气战略
  13. 远程数据库对象 Mmzrmo4Delphidelphi盒子
  14. pkg-config
  15. Big O, Big Omega, Big Theta的含义
  16. 淘丞相将微博链接转为淘宝直达是怎么实现的?
  17. 家用计算机相比工控机优点,具体分析工控机比一般的PC的优势
  18. SIEMENS/西门子1214 PID/通信模板 西门子P SIEMENS/西门子1214 PID/通信模板
  19. omnipeek安装步骤
  20. rufus-scheduler 定时任务示例

热门文章

  1. 最热网友收藏:写得蛮好的linux学习笔记(2007年第10周)
  2. 2021 OWASP TOP 10 漏洞指南
  3. 观点 | Keras之父谈人工智能:通用AI不会出现,超人类智能更不存在
  4. 什么是室内多芯分支光缆?室内多芯分支光缆技术规格参数介绍
  5. 什么性格的人适合报考环境科学类专业?高考选专业
  6. VMware虚拟机设置上网及与本地计算机通信
  7. indesign2019怎么存低版本_高版本的InDesign文档怎样存储为早期版本
  8. 全国Asp net程序员平均工资水平
  9. mac下 mysql data文件下的数据库恢复
  10. Git之GitFlow工作流 | Gitflow Workflow(万字整理,已是最详)