数据结构之链表深度讲解

news2024/11/28 21:00:29

小伙伴们,大家好呀,上次听我讲完顺序表想必收获不少吧,嘿嘿,这篇文章你也一样可以学到很多,系好安全带,咱们要发车了。

因为有了上一次顺序表的基础,所以这次我们直接进入正题,温馨提示:本篇文章的内容会比上次的顺序表文章的内容更加难,所以请耐心看完,过程中我会将一些难点,易混淆点给大家一一细讲,如有需要自行做笔记。


链表结构体内的元素

和顺序表里一样创建一个自定义类型的结构体,并且创建一个自定义类型的变量,以及指向下一个节点的指针next。

链表的尾插

链表和上次的顺序表一样也有尾插,那么我先教大家在链表头文件里如何写这个函数。也许会有小伙伴说函数不是很简单吗,而且看了博主这么多的文章,写个函数有何难呢。其实事情不是你想的那么简单,且听我细细道来。

首先,我们先来看一下两张图的区别

顺序表在测试文件中的尾插函数

链表在测试文件中的尾插函数

从图中我们可以看到俩图的区别

相同点:尾插时都是传了地址和要插入的数据

不同点:创建时,顺序表:结构体缩名   表名         链表:用指针的形式定义第一个节点   

那么这时我们也就可以在链表头文件内写尾插函数了,代码如下:

也许这时就会有人懵了,诶,我当时只是传了节点的地址呀,怎么这里就突然用了二级指针了?

所以说,话可不能说得太满。

之前我就已经详细的介绍了,我们在创建第一个节点时是以指针的形式创建,现在又传地址(也就是说传的是指针的地址)给尾插函数,所以这里就应该用二级指针啦。

那么基本上就给大家讲清楚啦,这是本篇文章的第一个难点

那么接下来我们来看看尾插代码主体部分具体怎么写吧。

思路:和顺序表一样先判断是否为空,因为我们创建好的第一个节点是空的,因此我们要去给它申请空间(这个函数具体怎么写放在下面,一会儿会简单讲一下),然后判断第一个节点是否为空,如果第一个节点为空,那么直接用“=”插入即可。温馨提醒:指针   =   指针的意思就是与变量与变量之间的赋值是一样的。那么当二级指针不为空时,我们需要以指针的形式创建尾节点,并且规定尾节点指向下一个的节点的地址不为空,也就是while(ptail->next),让ptail指针遍历链表,链表为空时插入数据。其中patil   =   ptail->next   的意思是ptail这个指针已经移到了下一个节点处, 那么   ptail->next   =    newnode  意思就是ptail指针连接到了newnode这个节点,但指针ptail还未移动到newnode处。为了方便大家理解,可以看一下下面的图

简单地给大家画了一下,差不多就这个意思,希望大家能理解。

那么尾插函数已经介绍完了,我们再来简单过一下链表中如何申请空间。

链表中申请节点空间

基本上和顺序表的差不太多,不一样的地方有顺序表里使用的是realloc(增容),而我们这里需要的是申请空间,因此我们可以用malloc,也可以使用calloc,大家有兴趣可以自己去尝试一下。申请完空间后,也许有人就不知道该干什么了,兄台别忘了我们是要把这个数据给尾插进去的呀,因此就得到了newnode->data =  x,插入完毕后也不要忘记将next指针置为空哦。

那么到此为止我们的链表尾插算是真正讲完了。尾插讲完后,我们就要开始起飞了,请各位小伙伴们系好安全带,飞机即将起飞。

链表的头插

链表头文件里的头插函数和上面图片里的一样,这里就不浪费文字去讲解了。毕竟我们主要还是将链表源文件的头插函数内部的写法和思路,首先我们来思考一个问题:假设我们就往一个空链表中进行插入数据,那么请问这个数据的插入方式究竟是头插还是尾插?想必大家的答案都是无法确定该数据的插入方式。因此我们可以从这里得到一个结论:头插数据时必须确保链表不为空,那么我们就可以确定这个函数上来就可以先给它断言:链表不为空。紧接着我们来看一下下面这张图

大家可以看到:这是一个不为空的链表,此时我们要头插数据,但是前面没有节点,因此我们需要创建节点,并且插入数据,因此也就有了代码图中的第二行代码,并且让newnode的next指针指向下一个节点,也就是我们在创建新节点之前的头节点pphead,并且此时pphead已经不再是头节点了,因此,我们需要用赋值符号“=”将pphead移到前面去(换句话说就是将两个指针互换了一下位置,但我不推荐这么理解)。

学习指南:看到这里的小伙伴如果感觉还吃得消,那么请继续看头插与尾插的拓展,如果有吃不消的小伙伴,可以先下滑看链表的尾删。

头插与尾插的拓展

指定位置的尾插

首先,我们需要确保所指定的位置不能为空,其次节点与节点之间没有空间,如图所示

因此我们需要使用malloc申请空间,创建新节点

创建完新的节点之后我们就要将其与其他节点连接起来,那么我们先连newnode的尾部吧,我们需要将newnode->next 指向原先pos所指向的下一个位置,也就是newnode->next   =    pos->next, newnode的前面就是与pos相连接即可,也就是让pos->next指向newnode

指定位置的头插

首先,我们需要确保链表不为空,并且头节点也不为空(为什么不能为空,一会给大家解释),对于我们来说最容易想到的是第二种情况

思路:我们需要定义一个新的指针使该指针从头节点phead开始,当prev的下一个节点是pos时,停下,并头插newnode这个节点。

第一种思路往往是我们容易忽略的一种

这种情况,我们只需要使用if语句,条件就是pos == phead即可,之后再调用一下我们指前写的头插函数将该数据插入就完成了,所以不明白*phead不能为空的小伙伴们恍然大悟了吗?

那么如何找到指定位置呢?

思路:我们先重新定义一个头节点pcur,通过循环找到与x相等的节点并返回即可

指定位置的删除

首先保证链表头节点和指定位置不为空,那么这里我们分两种情况讨论:

第一种:当指定位置就是头节点时,直接调用头删函数

第二种:也就是如下图这种情况时

先找到pos的前一个节点,让它的next指向pos的下一个节点,如图

最后就是释放掉pos并且置为空即可

指定位置的尾删

指定位置的尾删思路还是比较简单的,我这就给大家细细道来

思路:首先保证指定位置和指定位置的下一个节点不为空,为了便于大家可以清晰的分辨和理解,于是我定义了一个del指针让它代替pos->next,让pos->next = del->next,之后释放掉del并置为空。

链表的删除

 尾删:

思路:分两种情况讨论:

第一种:链表里只有一个节点时,直接释放掉*pphead,并且置为空即可,而判断它的条件:*pphead->next  ==  NULL;

第二种:连表里有多个节点时,先定义两个指针,使其中一个指针开始循环,另一个指针记录进行循环的指针的位置,当循环等指针的next指向空时,释放掉一开始循环的指针,并置为空,以及保存循环指针位置的指针的next也指向空

头删:

头删的思路比尾删的要简单许多,代码如下

保证链表和头节点不为空的情况下,先定义next指针,它负责接收*pphead的next指针指向的下一个节点,释放*pphead,最后将next赋给*pphead

链表的销毁

首先声明链表以及头节点的指针不为空,重新定义一个头节点指针prev,让prev进入循环,条件是prev不为空,进入循环后,重新定义一个指针next,它负责保存prev->next,然后释放掉prev, 再将next  的地址传给prev,跳出循环后将*pphead置为空,这样链表就销毁了。


当然这篇文章看下来,你可能还是会有些模糊,没事,我们不是还有总结环节嘛,下面就进入咱们的总结环节

总结:

1.    eg.prev->next   表示指针指向下一个节点,但指针还未移动

2.    eg.prev = prev->next   表示指针指向下一个节点,指针已经移动至下一个节点

3.    prev  =  pcur   表示pcur指针已经将它的地址和数值全传给了prev

4.    链表思路上的小妙招:去寻找插入以及删除节点时哪一个链条或哪几条链条被影响了,找到被影响的链条后,将其修改一下链接对象即可

5.关于pphead、 *pphead、**pphead还不清楚的同学可以参考一下下图


最后也祝大家在这个五一玩的开心

如果,你喜欢我的文章,不妨给我点个关注呗,如果有在这方面的问题也可以随时联系我哦

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

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

相关文章

Meta最新研究: Flash Attention 为何是系统性能瓶颈?

I. 引言 随着机器学习趋向于更大和更复杂的模型,模型训练过程变得越来越计算和资源密集。生成式AI的出现进一步推动了模型开发的边界,大型语言模型(LLMs)通常在数百或数千个GPU上训练数月。以LLaMA2的70-B参数模型为例,需要1,720,320 GPU小时来训练。对于如此长的训练作业,训练…

2024-05-07 商业分析-赚钱之前怎么预估风险-记录

摘要: 2024-05-07 商业分析-赚钱之前怎么预估风险-记录 赚钱之前怎么预估风险 好,大家好,今天我们来讲的是叫什么赚钱之前怎么评估风险啊,这个问题啊提的很好啊,我们待会儿来讲啊。呃,首先呢今天这个主题呢来自于昨天…

腾讯云服务器之ssh远程连接登录

一、创建密钥绑定实例 创建密钥会自动下载一个私钥,把这个私钥复制到c盘 二、设置私钥权限 1、删除所有用户权限 2、添加当前用户权限 查看当前用户名 echo %USERNAME%三、ssh远程连接到服务器 ssh ubuntu175.xxx.xxx.112 -i C:\Crack\cs2.pem四、修改root密码 s…

2024年荆州中级工程师报名开始了吗?

2024年荆州中级工程师职称报名已经开始了 2024年荆州中级职称报名时间: (一)网上报名时间: 4月26日9时至5月10日16时。超过时间将不能操作。 (二)网上缴费时间: 4月26日9时至5月10日24时 网上…

太原理工大学Python数据分析原理与应用(课外考题:8~11章)

这部分大概只考10分,且大部分出在选择题,填空最多一两个 (仅供参考) 第十章 (理解概念为主,无需看推导过程) 第十一章

常用算法汇总

作者:指针不指南吗 专栏:算法篇 🐾算法思维逻辑🐾 文章目录 1.判断闰年2.计算从某天到某天的天数3.二分4. 前缀和5.差分6.图论6.1dfs6.2走迷宫 7.最短路7.1dijkstra7.2foly 8.并查集9.数论9.1gcd lcm9.2判断素数(质数)9.3分解质因…

TCP经典异常问题探讨与解决

作者:kernelxing TCP的经典异常问题无非就是丢包和连接中断,在这里我打算与各位聊一聊TCP的RST到底是什么?现网中的RST问题有哪些模样?我们如何去应对、解决?本文将从RST原理、排查手段、现网痛难点案例三个板块自上而…

AIGC技术带给我们什么?基于AIGC原理及其技术更迭的思考

AIGC技术带给我们什么?基于AIGC原理以及技术更迭的思考 前言 AI,这个词在如今人们的视野中出现频率几乎超过了所有一切其他的事物,更有意思的是,出现频率仅次于这个词的,几乎都会加上一个修饰亦或是前缀——AI&#…

【刷题篇】双指针(一)

文章目录 1、移动零2、复写零3、快乐数4、盛最多水的容器 1、移动零 给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。 请注意 ,必须在不复制数组的情况下原地对数组进行操作。 class Solution { pub…

【机器学习系统的构建】从模型开发的过程讲清楚K-Fold 交叉验证 (Cross-Validation)的原理和应用

0、前言 最近在学习集成学习的时候了解到了k折交叉验证,其实在之前学习吴恩达老师的课程中也学过交叉验证,但是当时也不是很明白。这次借着自己的疑问以及网上搜找资料,终于把交叉验证给弄明白了。 在弄清楚前,我有这样几个疑问…

Windows系统和unbtun系统连接usb 3.0海康可见MVS和红外艾睿相机

一.海康可见USB3.0工业面阵相机 海康usb相机需要去海康官网上下载对应系统的MVS客户端及SDK开发包 海康机器人-机器视觉-下载中心 选择Windows系统和unbtun(我是linux aarch64,所以选择了对应压缩包解压) Windows系统 1.双击安装包进入安装界面&…

第三节课,前端

一、参考链接; 总 知识星球 | 深度连接铁杆粉丝,运营高品质社群,知识变现的工具 分 2022-03-18 星球直播笔记-用户中心(下) 语雀 二、登录 2.1登录网址 2.2前端页面修改 2.1 页面修改 2.2 页脚的超链接 网址&am…

机器学习算法--朴素贝叶斯(Naive Bayes)

一、实验环境 1. python3.7 2. numpy > 1.16.4 3. sklearn > 0.23.1 二、朴素贝叶斯的介绍 朴素贝叶斯算法(Naive Bayes, NB) 是应用最为广泛的分类算法之一。它是基于贝叶斯定义和特征条件独立假设的分类器方法。NB模型所需估计的参数很少,对缺…

25考研英语长难句Day02

25考研英语长难句Day02 【a.词组】【b.断句】 如果你是你讲话对象中的一员,你就能了解你们大家共同的经历和问题,你也可以顺便评论一下食堂里难吃的食物或董事长臭名昭著的领带品味。 【a.词组】 单词解释addressv. 演说, 演讲;…

【进程终止】概念理解 | 三种情况 | 退出码

目录 什么是进程终止 进程退出的场景 退出码 0退出码 !0系统退出码 非0自定义退出码 进程的终止从三个方面去谈。清楚进程终止是在做什么?进程终止的3中情况?如何终止?注意进程终止不是进程暂停。 什么是进程终止 ❓进程…

Map集合的实现类~HashMap

存储结构:哈希表 键重复依据是hashCode和equals方法(键不能重复) 添加: 先创建Student类,那么往HashSet添加的就是Student对象作为键值,后面的作为值 删除: 判断: 遍历&#xff1a…

Android 系统启动流程源码分析

一、Init进程启动 是一个由内核启动的用户级进程。内核自行启动之后,就通过启动一个用户级程序init的方式,完成引导进程。 启动的代码init.c中的main函数执行过程:system\core\init.c中: 主要下面两个重要的过程: 1…

每日OJ题_贪心算法三⑤_力扣134. 加油站

目录 力扣134. 加油站 解析代码 力扣134. 加油站 134. 加油站 难度 中等 在一条环路上有 n 个加油站,其中第 i 个加油站有汽油 gas[i] 升。 你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i1 个加油站需要消耗汽油 cost[i] 升。你从其中的一…

基于51单片机的ADC0804的电压表设计(仿真+源码+设计资料)

目录 1、前言 2、资料内容 3、仿真图 4、程序 资料下载地址:基于51单片机的ADC0804的电压表设计(仿真源码设计资料) 1、前言 最近看网上有很少的ADC0804的设计了,都由0809代替,但是有个别因为成本原因和学校课…

60、郑州大学附属肿瘤医院 :用于预测胃癌患者术后生存的深度学习模型的开发和验证[同学,我们的人生应当是旷野]

馒头老师要说的话: 我近期看了一下北京的脑机公司,大概是我之前对这一行业太过于乐观,北京的BCI公司和研究所,比上海、深圳、杭州甚至是重庆都要少,门槛也要高很多。也有我自己的原因,有时站的太高&#x…