数据结构——链表(单链表)

大家好,又是我(小锋),今天给大家带了一个比较有挑战的章节(链表),但是不用担心,小锋会陪大家一起度过。

顺序表的思考与问题

1. 中间/头部的插入删除,时间复杂度为O(N)
我们在进行一些插入删除操作时我们会先内存覆盖然后再进行操作,覆盖内存的时间复杂度为O(N)。
2. 增容需要申请新空间,拷贝数据,释放旧空间。会有不小的消耗。
当我们进行扩容时我们是不是要用realloc函数,而realloc函数再扩容时分为异地扩容,和原地扩容,当我们异地扩容时又有一系列的操作这又加大了消耗。
3. 增容一般是呈2倍的增长,势必会有一定的空间浪费。例如当前容量为100,满了以后增容到
200,我们再继续插入了5个数据,后面没有数据插入了,那么就浪费了95个数据空间。
我们增加容量后可能用不完,这就会造成空间的浪费,以及顺序表的空间是连续的我们要释放就必须全部释放。
那我们今天讲到链表就不会出现上面的问题,但也不是说链表就没有缺点,不论是顺序表还是链表都有优缺点,重点在于我们怎么运用。

链表

概念:链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表
中的指针链接次序实现的 。
我们这节主要讲解单链表
这个就是链表的逻辑结构了,一个节点中有指向下一个节点的指针,这样走下去最后一个节点中放的是空指针NULL,像链条一样一环扣一环。
我给大家画一个物理结构方便大家理解
我们可以形象看出链表的基本结构
那我们来创建一个链表
我们先来实现一个打印链表内容的函数

单链表打印

//链表输出void LBexport(LBbiao* att) {assert(att);LBbiao* ps = att;while (ps!= NULL) {printf("%d->", ps->SZ);ps = ps->next;}printf("NULL\n");}

这里大家可以画图一步一步的理一下理解会更加深刻主要注意循环的判断条件。

我们下面来实现一个插入函数

单链表头插数据

我们想一想在链表的头部插入数据我们只需要开辟一个链表空间mon然后另它的next指向当前链表的表头的地址,并将mon的地址交给表头的指针是不是就可以插入数据并且将链表连接起来了?

大家可以看看大致原理如图
我们还要注意要进行断言防止出现错误
//链表头插数据void LBcutin(LBbiao** att,CMMlet n) {assert(att);LBbiao* pt = LBopen();if (*att == NULL) {*att = pt;}else {pt->next = *att;*att = pt;}pt->SZ = n;}
这里开辟一个新的链表空间我们还会用到所有我们用一个函数来实现
//开辟链表LBbiao* LBopen() {LBbiao* mon = (LBbiao*)malloc(sizeof(CMMlet) + sizeof(LBbiao*));if (mon == NULL) {printf("开辟失败:%s",strerror(errno));return NULL;}mon->next = NULL;mon->SZ = 0;return mon;}
我们这里可以用老方法,分装一个函数来验证

单链表头删数据

还是我们用图来演示

//链表头删数据void LBdelete(LBbiao**att) {assert(*att != NULL);assert(att != NULL);//断言LBbiao* ps = *att;*att = ps->next;ps->next = NULL;free(ps);}

我们验证试试

单链表尾删数据

我们还是画图演示原理

我们可以看见尾删数据直接将倒数第二个节点的next为空就行了,当然我们还要断言一些情况

并且我们还要分情况当链表只有一个节点时该怎么删。

//链表尾删数据void LBweishan(LBbiao*att) {assert(att != NULL);//断言LBbiao* ps = att;while (ps->next->next != NULL) {ps = ps->next;}free(ps->next);ps->next = NULL;}

单链表尾插数据

老规矩画图理解

我们通过图可以看出尾插数据要开辟一个新的节点然后让原链表的最后一个节点的next指向新开辟出来的节点并将新开辟的节点的next为空。同样我们要分情况讨论

//链表尾插数据void LBweicha(LBbiao** att,CMMlet n) {LBbiao* ps = *att;LBbiao* pt = LBopen();if (ps == NULL) {*att = pt;}else {while (ps->next != NULL) {ps = ps->next;}ps->next = pt;}pt->SZ = n;}

单链表查找

我们可以直接遍历链表如果遇到我们就返回该数据的节点地址,如果没找到我们返回NULL。

//链表查找LBbiao* LBchazhao(LBbiao* att, CMMlet n) {assert(att);LBbiao* ps = att;while (ps != NULL) {if (ps->SZ == n) {return ps;break;}ps = ps->next;}return NULL;}

我们可以测试一下

单链表在pos位置之后插入x

与头插类似我们主要注意的是要不要分情况讨论,以及断言的内容,具体插入的过程我们大家可以自己画图试试

接下来我们来实现一下这个函数

//链表在pos位置后插入xvoid LBporcr(LBbiao* pos, CMMlet x) {assert(pos);LBbiao* ps = pos;LBbiao* pt = LBopen();if (pos->next == NULL) {//相当于尾插数据LBweicha(&pos, x);}else {//一般情况pt->next=ps->next;ps->next = pt;pt->SZ = x;}}

验证试试

单链表删除pos位置之后的值

我们还是用图说话

分析后我们发现我们只需要将pos位置的next指向pos->next->next就ok了,最后还要注意一下特殊情况以及断言

//链表在pos位置后删除xvoid LBpossc(LBbiao* pos) {assert(pos&&pos->next!=NULL);if (pos->next->next == NULL) {//相当于尾删free(pos->next);pos->next = NULL;}else {LBbiao* ps = pos->next;pos->next = pos->next->next;ps->next = NULL;free(ps->next);}}

我们可以测试一下

链表空间的释放

同学们,因为链表是环环相扣的我们如果将一个空间节点的空间释放那么我们就无法找到下一块空间了所有我们这里应该设置两个指针一个指向要释放空间的节点一个指向下一个节点,

//链表释放空间void LBshifang(LBbiao** att) {assert(att);assert(*att);LBbiao* ps = *att;LBbiao* pt = ps->next;while (ps) {ps->next = NULL;free(ps);ps = pt;if (pt!=NULL) {pt = pt->next;}}*att = NULL;}

​​​​​​​

我们测试一下

我们看是不是最后链表空间都被释放了?

同学们至此我们的单链表就讲解完了是不是畅快淋漓呢?

这是我们本节的所有代码大家可以自己试试

# define _CRT_SECURE_NO_WARNINGS 1
# include<stdio.h>
# include<assert.h>
# include<string.h>
# include<errno.h>
# include<stdlib.h>//类型重命名
//方便后期修改
typedef struct LBbiao LBbiao;
typedef int CMMlet;
//链表创建struct LBbiao{CMMlet SZ;//链表存储的数据struct LBbiao* next;//指向下一个节点};//开辟链表LBbiao* LBopen() {LBbiao* mon = (LBbiao*)malloc(sizeof(CMMlet) + sizeof(LBbiao*));if (mon == NULL) {printf("开辟失败:%s",strerror(errno));return NULL;}mon->next = NULL;mon->SZ = 0;return mon;}//链表输出void LBexport(LBbiao* att) {assert(att);LBbiao* ps = att;while (ps!= NULL) {printf("%d->", ps->SZ);ps = ps->next;}printf("NULL\n");}//链表头插数据void LBcutin(LBbiao** att,CMMlet n) {assert(att);LBbiao* pt = LBopen();if (*att == NULL) {*att = pt;}else {pt->next = *att;*att = pt;}pt->SZ = n;}//链表头删数据void LBdelete(LBbiao**att) {assert(*att != NULL);assert(att != NULL);//断言LBbiao* ps = *att;*att = ps->next;ps->next = NULL;free(ps);}//链表尾删数据void LBweishan(LBbiao**att) {assert(att != NULL);//断言assert(*att != NULL);LBbiao* ps = *att;if (ps->next == NULL) {*att = NULL;free(ps);}else {while (ps->next->next != NULL) {ps = ps->next;}free(ps->next);ps->next = NULL;}}//链表尾插数据void LBweicha(LBbiao** att,CMMlet n) {LBbiao* ps = *att;LBbiao* pt = LBopen();if (ps == NULL) {*att = pt;}else {while (ps->next != NULL) {ps = ps->next;}ps->next = pt;}pt->SZ = n;}//链表查找LBbiao* LBchazhao(LBbiao* att, CMMlet n) {assert(att);LBbiao* ps = att;while (ps != NULL) {if (ps->SZ == n) {return ps;break;}ps = ps->next;}return NULL;}//链表在pos位置后插入xvoid LBporcr(LBbiao* pos, CMMlet x) {assert(pos);LBbiao* ps = pos;LBbiao* pt = LBopen();if (pos->next == NULL) {//相当于尾插数据LBweicha(&pos, x);}else {//一般情况pt->next=ps->next;ps->next = pt;pt->SZ = x;}}//链表在pos位置后删除xvoid LBpossc(LBbiao* pos) {assert(pos&&pos->next!=NULL);if (pos->next->next == NULL) {//相当于尾删free(pos->next);pos->next = NULL;}else {LBbiao* ps = pos->next;pos->next = pos->next->next;ps->next = NULL;free(ps->next);}}//链表释放空间void LBshifang(LBbiao** att) {assert(att);assert(*att);LBbiao* ps = *att;LBbiao* pt = ps->next;while (ps) {ps->next = NULL;free(ps);ps = pt;if (pt!=NULL) {pt = pt->next;}}*att = NULL;}//测试链表1void ceshi1() {LBbiao* arr = NULL;LBweicha(&arr, 1);LBweicha(&arr, 2);LBweicha(&arr, 3);LBweicha(&arr, 4);LBshifang(&arr);}int main() {ceshi1();return 0;}

  以上就是全部内容了,如果有错误或者不足的地方欢迎大家给予建议。 

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

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

相关文章

从TCP/IP协议到socket编程详解

​ 我的所有学习笔记&#xff1a;https://github.com/Dusongg/StudyNotes⭐⭐⭐ ​ 文章目录 1 网络基础知识1.1 查看网络信息1.2 认识端口号1.3 UDP1.4 TCP1.4.1 确认应答机制1.4.2 TCP三次握手/四次挥手为什么是三次握手为什么是四次挥手listen 的第二个参数 backlog—— 全…

Day55:WEB攻防-XSS跨站CSP策略HttpOnly属性Filter过滤器标签闭合事件触发

目录 XSS跨站-安全防御-CSP XSS跨站-安全防御-HttpOnly XSS跨站-安全防御-XSSFilter(过滤器的意思) 1、无任何过滤 2、实体化 输入框没有 3、全部实体化 利用标签事件 单引号闭合 4、全部实体化 利用标签事件 双引号闭合 5、事件关键字过滤 利用其他标签调用 双引号闭合…

进程调度算法

进程调度算法 进程调度算法先来先服务调度基于优先级调度&#xff08;Priority Scheduling&#xff09;短进程优先 / 最短剩余时间优先轮转法&#xff08;Round-Robin Scheduling&#xff09;高响应比优先调度算法&#xff08;Highest Response Ratio Next&#xff09;多级反馈…

亚信安全联合人保财险推出数字安全保障险方案,双重保障企业数字化转型

数字化发展&#xff0c;新兴技术的应用与落地带来网络攻击的进一步演进升级&#xff0c;同时全球产业链供应链融合协同的不断加深&#xff0c;更让网络威胁的影响范围与危害程度不断加剧。 企业单纯依靠自身安全能力建设&#xff0c;能否跟上网络威胁的进化速度&#xff1f;能否…

使用nvm管理nodejs版本

文章目录 1、下载NVM2、选择NVM安装3 、查询版本号&常用命令4、nvm命令安装指定版本node4.1 安装指定node4.2 查看是否安装成功4.3 切换node版本到你想要的版本4.4 再次查看nvm版本列表4.5 nvm其他常用命令 这个是每个全能前端经常会用到的&#xff0c;之前用过现在重装了&…

目前现货黄金行情技术分析

目前行情黄金可以投资吗&#xff1f;不论是黄金价格怎么波动&#xff0c;总是有投资者问这个问题&#xff0c;原因是他们搞不清现状&#xff0c;弄不懂当前的市场形势&#xff0c;对于技术分析和基本分析的方法也不甚了解&#xff0c;因此缺乏对未来行情判断的能力。下面我们就…

探究分布式事务:深入ACID特性在分布式系统中的挑战与解决方案

✨✨谢谢大家捧场&#xff0c;祝屏幕前的小伙伴们每天都有好运相伴左右&#xff0c;一定要天天开心哦&#xff01;✨✨ &#x1f388;&#x1f388;作者主页&#xff1a; 喔的嘛呀&#x1f388;&#x1f388; ✨✨ 帅哥美女们&#xff0c;我们共同加油&#xff01;一起进步&am…

代码随想录训练营Day37:● 738.单调递增的数字 ● 968.监控二叉树 ● 总结

738.单调递增的数字 题目链接 https://leetcode.cn/problems/monotone-increasing-digits/description/ 题目描述 思路 从后往前遍历数字的每一位&#xff0c;如果前一位大于后一位&#xff0c;则将其减一&#xff0c;后边的一位取 i-9 中最大的 解答的两点疑惑&#xff1a;…

类中属性赋值过程

1 、在类的属性中&#xff0c;可以有哪些位置给属性赋值&#xff1f; ① 默认初始化 package chapter06_oop1.src.com.atguigu09.bean_uml;public class UserTest {public static void main(String[] args) {User u1 new User();System.out.println(u1.age);} }class User{/…

【深度学习目标检测】二十四、基于深度学习的疲劳驾驶检测系统-含数据集、GUI和源码(python,yolov8)

设计一个疲劳驾驶检测系统的重要性主要体现在以下几个方面&#xff1a; 提高道路安全&#xff1a;疲劳驾驶是引发交通事故的重要因素之一。驾驶员在长时间驾驶或缺乏休息的情况下&#xff0c;反应速度和判断能力会显著下降&#xff0c;从而增加事故风险。通过实时检测驾驶员的疲…

基于Websocket的局域网聊天系统

1.1 研究背景及意义 本项目所对应领域的研究背景及意义[1]。新冠肺炎局域网通信发生以来&#xff0c;大数据、云计算、人工智能等新一代信息技术加速与交通、局域网通信、教育、金融等领域深度融合&#xff0c;让局域网通信防控的组织和执行更加高效&#xff0c;成为战“疫”的…

【Frida】【Android】06_夜神模拟器中间人抓包

&#x1f6eb; 系列文章导航 【Frida】【Android】01_手把手教你环境搭建 https://blog.csdn.net/kinghzking/article/details/136986950【Frida】【Android】02_JAVA层HOOK https://blog.csdn.net/kinghzking/article/details/137008446【Frida】【Android】03_RPC https://bl…