【数据结构与算法 经典例题】随机链表的复制(图文详解)

 

        258650adc14741f987d9eeb54b929d23.png

            💓 博客主页:倔强的石头的CSDN主页 

             📝Gitee主页:倔强的石头的gitee主页

   ⏩ 文章专栏:《数据结构与算法 经典例题》C语言

                                  期待您的关注

1b7335aca73b41609b7f05d1d366f476.gif

目录

一、问题描述

二、解题思路

三、代码实现

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

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

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

完整代码


一、问题描述

习题摘自

 138. 随机链表的复制 - 力扣(LeetCode)

二、解题思路

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


分三步走

  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.原链表中节点的随机指针拷贝

注意:

随机指针不是单纯的拷贝,而是将拷贝节点的随机指针指向与原链表中关系对应的拷贝节点

第二个循环:

  • pcur指针重新指向第一个节点,重新遍历链表
  • 进入循环
  • 拷贝指针指向pcur的下一个节点
  • 如果pcur指针指向节点的随机指针指向NULL,拷贝节点的随机指针则相同
  • 否则拷贝节点每次指向pcur指针指向节点的下一个节点
  • 修改拷贝节点的随机指针,令其指向pcur指针指向节点的随机指针指向的节点的下一个节点
  • 然后pcur指针指向拷贝节点的下一个节点,拷贝指针指向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指针拷贝,拷贝节点成为单独的新链表 

第三个循环:

  • pcur指针重新指向链表第一个节点
  • 创建新链表的头指针和尾指针初始都指向空
  • 进入循环——拷贝指针指向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;

完整代码

/*** 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;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/23176.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

采用JWT令牌和Filter进行登录拦截认证

原理描述: 1、第一次登录的时候,生成JWT令牌,并JWT令牌存放在localStorage。 localStorage.setItem(token, token); 2、每次通过axios发送请求的时候,都将这个令牌获取,并放于header中发送。 也就是JWT令牌只在登录…

PCL 抛物线回归拟合(Quadratic,二维)

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 这里仍然是最小二乘法的应用,其推导过程如下所述: 1.二次函数模型: 其中,a、b 和 c 是需要确定的参数。 2.最小二乘法 假设我们有一组数据点 ( x 1 ​ , y

实用软件分享---中医自学宝典(安卓)

专栏介绍:本专栏主要分享一些实用的软件(Po Jie版); 声明1:软件不保证时效性;只能保证在写本文时,该软件是可用的;不保证后续时间该软件能一直正常运行;不保证没有bug;如果软件不可用了,我知道后会第一时间在题目上注明(已失效)。介意者请勿订阅。 声明2:本专栏的…

usb设备在主机和VMWare虚拟机中切换连接

操作:点击菜单栏虚拟机(M)>可移动设备>选择自己的usb设备>连接(断开与 主机 的连接)

【Vue】路由介绍

一、引入 思考 单页面应用程序,之所以开发效率高,性能好,用户体验好 最大的原因就是:页面按需更新 比如当点击【发现音乐】和【关注】时,只是更新下面部分内容,对于头部是不更新的 要按需更新&#xff…

上海亚商投顾:沪指震荡下跌 两市成交不足7000亿元

上海亚商投顾前言:无惧大盘涨跌,解密龙虎榜资金,跟踪一线游资和机构资金动向,识别短期热点和强势个股。 一.市场情绪 沪指昨日震荡调整,创业板指冲高回落。车路云概念股持续活跃,万通智控、鸿泉物联、华体…

【Vue】异步更新 $nextTick

文章目录 一、引出问题二、解决方案三、代码实现 一、引出问题 需求 编辑标题, 编辑框自动聚焦 点击编辑,显示编辑框让编辑框,立刻获取焦点 即下图上面结构隐藏,下面结构显示,并且显示的时候让它自动聚焦。 代码如下 问题 “…

【Multi-Feature FAS】《Face Anti-Spoofing Based on Multi-Feature Fusion》

文章目录 原文贡献 / 相关工作作者的方法评价 原文 [1]杨敏.基于多特征融合的人脸防伪技术研究[D].武汉大学,2019. 贡献 / 相关工作 针对攻击对象存在背景依赖和非刚性运动造成的深度信息缺失问题,采用边缘信息放大差异 各种 loss 数据库 评价指标 本节将会对…

Java——Stream流(2/2):Stream流的中间方法、终结方法(方法、案例演示)

目录 Stream流的中间方法 方法 案例演示 Stream流的终结方法 方法 案例演示1 收集 案例演示2 Stream流的中间方法 方法 中间方法指的是调用完成后会返回新的Stream流&#xff0c;可以继续使用(支持链式编程)。 Stream提供的常用中间方法说明Stream<T> filter(P…

gkuubibiih

c语言中的小小白-CSDN博客c语言中的小小白关注算法,c,c语言,贪心算法,链表,mysql,动态规划,后端,线性回归,数据结构,排序算法领域.https://blog.csdn.net/bhbcdxb123?spm1001.2014.3001.5343 给大家分享一句我很喜欢我话&#xff1a; 知不足而奋进&#xff0c;望远山而前行&am…

vue2的element的table组件使用form校验

1.需求描述 vue2有时候做自增表格el-table&#xff0c;希望能够带一些校验&#xff0c;但又不想手搓校验逻辑&#xff0c;可以借用el-form的校验逻辑。 2.代码处理 1. html <template><div class"sad-cont"><el-form ref"form" :model&…

LabVIEW传感器虚拟综合实验系统

LabVIEW传感器虚拟综合实验系统 开发了一个基于LabVIEW的传感器虚拟综合实验系统&#xff0c;该系统集成了NIELVIS和CSY系列传感器实验平台&#xff0c;通过图形化编程语言进行数据处理和实验管理。系统允许用户进行多种传感器参数的测量和实验报告的自动生成&#xff0c;支持…

不装了,我是知识星球的星主,我摊牌了~

作者&#xff1a;哈哥撩编程 &#xff08;视频号同名&#xff09; 图书作者&#xff1a;程序员职场效能宝典 博客专家&#xff1a;全国博客之星第四名 超级个体&#xff1a;COC上海社区主理人 特约讲师&#xff1a;谷歌亚马逊分享嘉宾 科技博主&#xff1a;极星会首批签约…

关系代数与规范化

本文是根据自己的理解&#xff0c;结合实践整理所得&#xff0c;有兴趣的可以参考学习。

文章解读与仿真程序复现思路——电网技术EI\CSCD\北大核心《基于麻雀搜寻优化算法的代理购电用户用电量多维度协同校核》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

php: centos+apache 启动php项目

指导文件 &#xff1a;PHP: Apache 2.x on Unix systems - Manual 下载路径 &#xff1a;Index of /httpd configure: error: APR not found. 解决方案&#xff1a; APR&#xff08;Apache Portable Runtime&#xff09;库。APR是Apache HTTP服务器的可移植运行时环境&…

前端列表可滚动,可轮播

前端列表可滚动&#xff0c;可轮播 <ulclass"scroll-list"ref"scroll_List"mouseenter"cancelScroll()"mouseleave"autoScroll()"><liclass"list-item"v-for"(item,index) in tableData3":class"[…

VMware workstations 安装华为OpenEuler操作系统,以及UKUI桌面环境的安装

现在华为OpenEuler操作系统官网下载&#xff0c;此次OpenEuler操作系统版本为20.03LTS-SP3&#xff0c;下载链接如下&#xff1a; https://www.openeuler.org/zh/download/archive/ 下载成功后如下图所示&#xff1a; 使用VMware workstations 进行安装&#xff08;VMware w…

ES6真题合集(一)

ES6真题合集&#xff08;一&#xff09; 1. var、let、const之间的区别2. ES6中数组新增了哪些扩展2.1 扩展运算符2.2 Array.from() 方法2.3 Array.of() 方法2.4 find() 和 findIndex() 方法2.5 箭头函数2.6 模板字符串 3. ES6中对象新增了哪些扩展3.1 属性的简写3.2 属性名表达…

vue2中使用tinymce

vue2中使用tinymce的记录 本篇文章主要实现的功能&#xff1a; &#xff08;1&#xff09;【查看】时禁用编辑 &#xff08;2&#xff09;【编辑】时某些内容是不可编辑的 &#xff08;3&#xff09;【内容】前端拼接编辑器模板 &#xff08;4&#xff09;【内容】编辑器模板中…