【数据结构和算法初阶(C语言)】复杂链表(随机指针,随机链表的复制)题目详解+链表顺序表结尾

目录

 1.随机链表的复制

1.2题目描述 

1.3题目分析

1.4解题:

2.顺序表和链表对比

2.1cpu高速缓存利用率

3.结语


 1.随机链表的复制

一个长度为 n 的链表,每个节点包含一个额外增加的随机指针 random 

该指针可以指向链表中的任何节点或空节点。 

 

 

 

1.2题目描述 

构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成,其中每个新节点的值都设为其对应的原节点的值。新节点的 next 指针和 random 指针也都应指向复制链表中的新节点,并使原链表和复制链表中的这些指针能够表示相同的链表状态。复制链表中的指针都不应指向原链表中的节点 

例如,如果原链表中有 X 和 Y 两个节点,其中 X.random --> Y 。那么在复制链表中对应的两个节点 x 和 y ,同样有 x.random --> y 。

返回复制链表的头节点。

用一个由 n 个节点组成的链表来表示输入/输出中的链表。每个节点用一个 [val, random_index] 表示:

  • val:一个表示 Node.val 的整数。
  • random_index:随机指针指向的节点索引(范围从 0 到 n-1);如果不指向任何节点,则为  null 。

你的代码  接受原链表的头节点 head 作为传入参数。

1.3题目分析

首先,链表的拷贝如果是普通链表的话,使用遍历+尾插即可。

深度拷贝就是要链表结构也一样

但是由于随机指针的存在。我们没办法知道或者就是说我们拷贝的节点的随机指针该指向那个位置。那么就有一种简单粗暴的方法:

遍历链表然后匹配随机指针。

那么巧妙的一种办法,就是将复制的节点插到被复制节点的后面,这种方法巧妙。时间复杂度为O(N).空间复杂度也为O(1).

while(cur)//循环申请插入{//每次都申请节点struct Node* copy = ( struct Node*)malloc(sizeof( struct Node));//尾插cur->val = copy->val;cur ->next = copy;copy->next = next;cur = next;//往后走一步next = cur->next;}

 那么对于随机指针的连接:

我们发现,我们原链表的节点的随机指针指向的节点的next刚好就是我们复制链表节点的随机指针要指向的节点,所以:

 //还要使用cur遍历cur = head;struct Node* copy = cue->next;while(cur){if(cur->random == NULL){copy->random = NULL;}else{copy->random = cur->random->next;}cur = copy->next;copy = cur->next;}

然后我们将复制的节点从原链表取下来尾插成新的链表,复原原链表就OK了:

1.4解题:

 

struct Node* copyRandomList(struct Node* head) {//1.首先先将复制的节点尾插到各个节点的后面assert(head);//断言,不能传入一个空链表struct Node* cur = head;struct Node* next = cur->next;while(cur)//循环申请插入{//每次都申请节点struct Node* copy = ( struct Node*)malloc(sizeof( struct Node));//尾插cur->val = copy->val;cur ->next = copy;copy->next = next;cur = next;//往后走一步next = cur->next;}//还要使用cur遍历cur = head;struct Node* copy = cur->next;while(cur){if(cur->random == NULL){copy->random = NULL;}else{copy->random = cur->random->next;}cur = copy->next;copy = cur->next;}cur = head;struct Node* copyhead = NULL;//新链表的头结点struct Node* copytail = NULL;//定义一个尾结点方便尾插//还是遍历解除复原while(cur){copy = cur->next;next = copy->next;//将cope结点开始尾插if(copytail == NULL)//此时新链表一个元素都没有{copyhead = copytail = copy;}else{copytail->next = copy;copytail = copytail->next;}cur ->next = next;cur =next;}return copyhead;}

2.顺序表和链表对比

    不同点                 顺序表                                                                   链表

存储空间上    物理上一定连续                                           逻辑上连续,但物理上不一定 连续

随机访问         支持O(1)                                                            不支持:O(N)

 任意位置插入或者删除元素可能需要搬移元素,效率低 O(N)     只需修改指针指向 

插入          动态顺序表,空间不够时需要 扩容                                没有容量的概念

应用场景       元素高效存储+频繁访问                                    任意位置插入和删除频繁 

缓存利用率                    高                                                                  低

2.1cpu高速缓存利用率

硬件上的存储分层如下图:

 

3.结语

 链表和顺序表的知识到这里基本就告一段落,那么大家可以从知识到解题详细回顾一下。

可以结合图解多看一下代码,结合理解。以上就是本期的所有内容,知识含量蛮多,大家可以配合解释和原码运行理解。创作不易,大家如果觉得还可以的话,欢迎大家三连,有问题的地方欢迎大家指正,一起交流学习,一起成长,我是Nicn,正在c++方向前行的奋斗者,数据结构内容持续更新中,感谢大家的关注与喜欢。

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

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

相关文章

Godot自定义控件样式语法解析

前言 本篇原始文章写于2023年8月7日,存储在我的语雀文档中。但是语雀分享有诸多不便,为了让更多Godoter更轻松的搜到和看到,就转过来了。 这个项目我上传了Github,后续会贴上链接。 概述 Godot控件体系存在的问题之一就是样式无…

【pyinstaller打包记录】Windows系统打包exe后,onnxruntime报警告(Init provider bridge failed)

简介 PyInstaller 是一个用于将 Python 程序打包成可执行文件(可执行程序)的工具。它能够将 Python 代码和其相关的依赖项(包括 Python 解释器、依赖的模块、库文件等)打包成一个独立的可执行文件,方便在不同环境中运行…

凌风 TEMU工具箱 抢仓 库存销售数据利润计算 选品监控采集上品 一网打尽

凌风TEMU工具箱介绍 一、安装教程1、下载方式2、环境准备3、安装步骤3.1、插件安装3.2、客户端安装 4、启动软件 二、使用教程一:登录注册激活方法2.1 注册登录2.2 激活方式 (激活码激活)2.3 绑定店铺 二:使用方法:功能…

Android Gradle开发与应用 (四) : Gradle构建与生命周期

1. 前言 前几篇文章,我们对Gradle中的基本知识,包括Gradle项目结构、Gradle Wrapper、GradleUserHome、Groovy基础语法、Groovy语法概念、Groovy闭包等知识点,这篇文章我们接着来介绍Gradle构建过程中的知识点。 2. Project : Gradle中构建…

揭秘大气颗粒物与VOCs:PMF源解析技术全解析

在现今日益严峻的环境问题中,大气颗粒物和臭氧污染尤为突出,它们不仅深刻影响着全球气候和生态环境,更对人体健康构成了严重威胁。为了有效应对这一挑战,我们首先需要深入了解颗粒物和臭氧的来源,特别是臭氧的前体物之…

遥测终端助力城市内涝积水监测,守护城市生命线!

近年来,随着全球气候的变化和城市化进程的加速,强降雨事件频发,导致城市内涝问题日益严重。道路低洼处、下穿式立交桥和隧道在强降雨时常常产生大量积水,给人们的出行带来极大不便,严重时甚至威胁人民的生命安全和造成…

JVM运行时数据区——方法区

文章目录 1、栈、堆、方法区的交互关系2、方法区的理解2.1、方法区的官方描述2.2、方法区的基本理解2.3、JDK中方法区的变化 3、设置方法区大小与OOM3.1、设置方法区内存的大小3.2、方法区内存溢出 4、方法区的内部结构4.1、类型信息、域信息和方法信息介绍4.1.1、类型信息4.1.…

动手学深度学习—循环神经网络RNN详解

循环神经网络 循环神经网络的步骤: 处理数据 将数据按照批量大小和时间步数进行处理,最后得到迭代器,即每一个迭代的大小是批量大小时间步数,迭代次数根据整个数据的大小决定,最后得出处理的数据(参照第三…

重拾前端基础知识:JavaScript

重拾前端基础知识:JavaScript 前言使用JavaScript输出语法运算符条件语句循环数据类型字符串数字数组对象日期函数 数学正则表达式异常处理类集合模块JSON闭包异步调试DOM(文档对象模型)事件事件监听器表单 BOM(浏览器对象模型&am…

【排序】详解选择排序

一、思想 选择排序的原理与思想非常直观和简单,它通过不断地选择未排序部分的最小(或最大)元素,并将其放到已排序部分的末尾来实现排序。 具体来说,选择排序的过程可以分解为以下几个步骤: 寻找最小&…

三步骤找到用户真正痛点 提高需求分析质量

用户痛点对于需求分析具有至关重要的作用,这直接关系着需求分析结果是否真正满足用户需求,关系着最终研发的产品是否能够满足市场的需求,是否能够在竞争激烈的市场中脱颖而出。因此找到用户真正痛点至关重要。 1、什么是痛点 痛点是消费者心理…

DML相关操作

DML 是数据操作语言,用来对数据库中表的数据记录进行增删改操作 添加数据(insert)修改数据(update)删除数据(delete) DML-添加数据 1.给指定字段添加数据 insert into 表名(字段…

各中间件性能、优缺点对比

参考资料: Kafka、ActiveMQ、RabbitMQ、RocketMQ 有什么优缺点?

C++命名空间

在C/C中,变量,函数和和类这些名称都存在于全局作用域中,可能会导致很多冲突,使用命名空间的目的是对标识符的名称进行本地化,避免命名冲突或名字污染,namespace关键字就是解决这种问题的。如下程序并无问题…

文物保护平台数据统计分析及预警-子系统专题分析

文物预防性监测与调控系统的监测统计分析子系统提供全面的文物状态及环境数据分析,为博物馆工作人员进行基于文物材质特性的专项保护提供相关科研辅助。主要的监测分析,包括各展厅文物统计分析、不同环境因素报表统计、以及监测调控设备统计分析等。 系统用户和文物管理人员可以…

从0开始入门智能知识库和星火大模型,打造AI客服。

介绍FastWiki FastWiki是一个高性能、基于最新技术栈的知识库系统,旨在为大规模信息检索和智能搜索提供解决方案。它采用微软Semantic Kernel进行深度学习和自然语言处理,在后端使用MasaFramework,前端采用MasaBlazor框架,实现了…

Swing程序设计(11)动作事件监听器,焦点事件监听器

文章目录 前言一、事件监听器是什么?二、详细展开 1.动作事件监听器2.焦点事件监听器总结 前言 如果你是坚持从Swing程序第一篇看到了这里,恭喜你,Swing程序设计简单地落下了帷幕,关于Swing程序更深的了解,可以自行学习…

MySQL性能优化-范式设计和反范式设计

范式化设计 范式化设计背景 范式是数据表设计的基本原则,又很容易被忽略。很多时候,当数据库运行了一段时间之后,我们才发现数据表设计得有问题。重新调整数据表的结构,就需要做数据迁移,还有可能影响程序的业务逻辑…

【Axure高保真原型】输入宽高控制图片尺寸

今天和大家分享输入图片宽高控制图片尺寸的原型模板,在输入框里输入图片的宽和高,图片会自动设置成对应数值的尺寸,包括了按比例或者自由设置两种方式,具体效果可以观看下方视频或者打开预览地址体验。 【原型效果】 【Axure高保…

数据库SQLite

1.简单创建一个数据库和删除一个数据库 <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"match_parent"android:orientation"vertical">&l…