当前位置: 首页 > news >正文

【数据结构算法经典题目刨析(c语言)】随机链表的复制(图文详解)

💓 博客主页:C-SDN花园GGbond

⏩ 文章专栏:数据结构经典题目刨析(c语言)

目录

一、题目描述

二、思路分析 

三、代码实现 


 

一、题目描述

二、思路分析 

要完成一个带随机指针的链表的复制,有一个巧妙的办法:分三步走

1.完成节点数据拷贝——在原链表的每个节点后面增加一个拷贝节点,拷贝节点的值等于原节点的值
2.完成节点的随机指针拷贝——原节点的随机指针指向哪里,拷贝节点就指向对应节点的下一个节点(这一部分是这条思路能实现的关键)
3.完成节点的next指针拷贝——将拷贝节点从原链表中取下,按顺序改变next指针指向,组成新的链表,并恢复原链表的next指针(也可不恢复)

 

1. 原链表中节点的数据拷贝 

  • 创建pcur指针指向链表第一个节点,遍历链表
  • 在每个节点后面创建一个相同结构的拷贝节点,拷贝原节点数据
  • 修改链表next指针指向如下:
  • 原链表节点->该节点拷贝节点->原链表下一个节点->该节点拷贝节点……原链表最后一个节点->该节点拷贝节点->NULL

 经过第一轮循环后,原链表每个节点之后被插入了一个新节点

 

这一部分的实现代码如下 

/*** Definition for a Node.* struct Node {*     int val;*     struct Node *next;*     struct Node *random;* };*/
typedef struct Node Node;
struct Node* copyRandomList(struct Node* head) 
{Node* pcur=head;while(pcur){Node*copy=(Node*)malloc(sizeof(Node));//创建拷贝节点copy->val=pcur->val;//拷贝数据copy->next=pcur->next;//插入到pcur后面pcur->next=copy;pcur=copy->next;//移动pcur指针}
}

2.原链表中节点的随机指针拷贝 

1.pcur指针重新指向第一个节点,重新遍历链表
进入循环
2.拷贝指针指向pcur的下一个节点
3.如果pcur指针指向节点的随机指针指向NULL,拷贝节点的随机指针则相同
否则拷贝节点的随即指针指向pcur的随机指针的下一个节点

 

 

这一部分实现代码如下

pcur=head;//指针重置while(pcur)//链表随机指针拷贝{Node*copy=pcur->next;if(pcur->random==NULL)copy->random=NULL;//对指向NULL的情况额外处理else{copy->random=pcur->random->next;//随机指针拷贝的关键}pcur=copy->next;}

3.原链表中节点的next指针拷贝,拷贝节点成为单独的新链表  

1.pcur指针重新指向链表第一个节点
2.创建新链表的头指针和尾指针初始都指向空
3.进入循环——拷贝指针指向pcur的下一个节点
next指针指向拷贝指针的下一个节点
接下来将拷贝节点尾插到新链表,并恢复原链表
如果新链表为空,则新链表首尾指针都指向拷贝节点
否则,新链表尾指针的next指向拷贝节点,然后尾指针指向拷贝节点
再将pcur指针指向节点的next指向next指针对应的节点
循环直到pcur走向NULL

这一部分的实现代码如下(并恢复的代码)

pcur=head;Node*newhead=NULL,*newtail=NULL;while(pcur){Node*copy=pcur->next;//指向要拷贝的节点Node*next=copy->next;//指向原链表原本的下一个节点if(newhead==NULL)//将拷贝节点尾插到新链表上{newhead=newtail=copy;}else{newtail->next=copy;newtail=copy;}pcur->next=next;//恢复原链表pcur=next;}return newhead;

不恢复的代码 

pcur=head->next;struct Node*newhead=NULL;struct Node*newtail=NULL;newhead=newtail=head->next;while(pcur->next){pcur=pcur->next->next;newtail->next=pcur;newtail=pcur;}newtail->next=NULL;return newhead; 

三、代码实现 

/*** Definition for a Node.* struct Node {*     int val;*     struct Node *next;*     struct Node *random;* };*/
typedef struct Node Node;
struct Node* copyRandomList(struct Node* head) 
{Node* pcur=head;while(pcur)//链表数据拷贝{Node*copy=(Node*)malloc(sizeof(Node));//创建拷贝节点copy->val=pcur->val;//拷贝数据copy->next=pcur->next;//插入到pcur后面pcur->next=copy;pcur=copy->next;//移动pcur指针}pcur=head;//指针重置while(pcur)//链表随机指针拷贝{Node*copy=pcur->next;if(pcur->random==NULL)copy->random=NULL;//对指向NULL的情况额外处理else{copy->random=pcur->random->next;//随机指针拷贝的关键}pcur=copy->next;}pcur=head;Node*newhead=NULL,*newtail=NULL;while(pcur){Node*copy=pcur->next;//指向要拷贝的节点Node*next=copy->next;//指向原链表原本的下一个节点if(newhead==NULL)//将拷贝节点尾插到新链表上{newhead=newtail=copy;}else{newtail->next=copy;newtail=copy;}pcur->next=next;//恢复原链表pcur=next;}return newhead;
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【人工智能】Transformers之Pipeline(三):文本转音频(text-to-audio/text-to-speech)
  • 仓颉语言 -- 宏
  • vue项目中,前端如何配置跨域请求
  • C语言 -- 动态内存管理
  • Node.js(2)——压缩前端html
  • 为什么Transformer需要进行 Multi-head Attention?
  • Vue Router 路由守卫详解
  • 未来3-5年,哪些工作会被AI取代
  • 【vluhub】skywalking
  • 设计学习笔记8:在设计模式中,状态模式和策略模式有什么区别,它们各自适用于什么场景?
  • ssh 非对称加密
  • 【动态规划】路径问题
  • C#中类和结构体的对比
  • Hive中分区(Partition)和分桶(Bucket)区别
  • MBA留学选校中Location的四大考量因素
  • 【译】React性能工程(下) -- 深入研究React性能调试
  • Codepen 每日精选(2018-3-25)
  • CSS 专业技巧
  • es6--symbol
  • LeetCode刷题——29. Divide Two Integers(Part 1靠自己)
  • Next.js之基础概念(二)
  • Python学习笔记 字符串拼接
  • 从零开始的webpack生活-0x009:FilesLoader装载文件
  • 全栈开发——Linux
  • 深度学习中的信息论知识详解
  • 使用parted解决大于2T的磁盘分区
  • 学习笔记:对象,原型和继承(1)
  • 【运维趟坑回忆录 开篇】初入初创, 一脸懵
  • Spring Batch JSON 支持
  • ## 1.3.Git命令
  • #[Composer学习笔记]Part1:安装composer并通过composer创建一个项目
  • ( 用例图)定义了系统的功能需求,它是从系统的外部看系统功能,并不描述系统内部对功能的具体实现
  • (C++)八皇后问题
  • (附源码)springboot建达集团公司平台 毕业设计 141538
  • (附源码)计算机毕业设计ssm本地美食推荐平台
  • (未解决)macOS matplotlib 中文是方框
  • (循环依赖问题)学习spring的第九天
  • *p++,*(p++),*++p,(*p)++区别?
  • .bat批处理(三):变量声明、设置、拼接、截取
  • .net core 6 使用注解自动注入实例,无需构造注入 autowrite4net
  • .NET Core工程编译事件$(TargetDir)变量为空引发的思考
  • .NET IoC 容器(三)Autofac
  • .NET Standard 支持的 .NET Framework 和 .NET Core
  • .net wcf memory gates checking failed
  • .NET(C#、VB)APP开发——Smobiler平台控件介绍:Bluetooth组件
  • .NET成年了,然后呢?
  • .net专家(高海东的专栏)
  • .pub是什么文件_Rust 模块和文件 - 「译」
  • /dev/VolGroup00/LogVol00:unexpected inconsistency;run fsck manually
  • [ vulhub漏洞复现篇 ] AppWeb认证绕过漏洞(CVE-2018-8715)
  • [ACTF2020 新生赛]Upload 1
  • [AI aider] 打造终端AI搭档:Aider让编程更智能更有趣!
  • [BZOJ] 3262: 陌上花开
  • [C#学习笔记]Newtonsoft.Json
  • [docker] Docker容器服务更新与发现之consul