首页/新闻资讯/正文详情

数据结构——单链表

发布时间:2026/9/24 20:21:10 来源:云帆数科 栏目:资讯中心
数据结构——单链表
目录1、链表的定义2、链表的分类1、不带头结点的单向不循环链表2、带头结点的单向不循环链表3、不带头结点单向循环链表4、带头结点的单向循环链表5、不带头结点的双向不循环链表6、带头结点的双向不循环链表7、不带头结点的双向循环链表8、带头节点的双向循环链表链表的结构1、结构2、创造一个节点3、初始化链表4、求链表长度5、打印链表6、查找元素根据数值查找根据下标查找7、插入根据下标插入头插尾插8、删除根据下标删除头删尾删9、销毁前言上次介绍了一种数据的存储结构——顺序表但是他会有缺陷当我们要插入元素和申请空间的时候一般情况下后扩容原来的2倍但是不一定每一个空间都装数据这样会造成空间的浪费而且进行插入和删除的时候对应实现的接口的时间复杂的位ON效率第因此一些大佬有发明了一个链表。下面是单链表的介绍。1、链表的定义链表Linked List是一种线性表由一系列节点Node组成每个节点包含数据域和指针域节点之间通过指针链接在一起。2、链表的分类链表的分类有很多种如下主要看他三个方面是否单向是否带头结点是否循环这样就有了八种链表。注意节点现代和结点偏传统这两种叫法都可以。下面是链表的具体情况在介绍链表的具体情况之前先区分一下头结点和头指针头结点也称为哨兵位他和普通的节点在结构上是一样的也分为数值域和指针域只不过他的数值域不存储有效数据然后他的指针域指向的是第一个有效节点的地址。头指针他仅仅是一个结构体类型的指针用于存储节点的地址他是链表最开始的部分。1、不带头结点的单向不循环链表2、带头结点的单向不循环链表3、不带头结点单向循环链表4、带头结点的单向循环链表5、不带头结点的双向不循环链表6、带头结点的双向不循环链表7、不带头结点的双向循环链表8、带头节点的双向循环链表链表的结构下面是对有头结点的不循环单链表的介绍1、结构//List.h #include stdio.h #include stdlib.h #include stdbool.h #include assert.h typedef int LDataType; //定义数值域存放的是int的类型的变量利用LDataType代替方便对数值域的类型进行修改 typedef struct ListNode { LDataType data; // 存储数据 struct ListNode* next; // 存放后继结点地址 }LNode, *LinkList;这里对LDataType进行重命名以至于对链表数值的存储方便修改更具有普适性。定义结构体变量需要注意这里的struct ListNode* next不能写成LNode*或者是*LinkList因为这里next是在重命名之前的。还要知道这里有一个typedef和结构体的知识struct ListNodeLNode; struct ListNode**LinkList2、创造一个节点List.h //创造一个新的节点节点的数值域是data LNode* BuyListNode(int data); //List.c //创造一个新的节点节点的数值域是data LNode* BuyListNode(int data) { LNode* newNode (LNode*)malloc(sizeof(LNode*)); if (newNode NULL) { printf(malloc创建空间失败); exit(-1); } newNode-data data; newNode-next NULL; return newNode; }这里创造完节点之后要判空而且要把节点的next置为空防止野指针还要返回节点的地址是为了能让链表之间的节点连起来。3、初始化链表//List.h LNode* ListInit(); //List.c LNode* ListInit() { LNode* node BuyListNode(-1);//头结点,初始化完了之后只有他一个 return node; }这里初始化的是有头结点的链表随便给他一个-1的值4、求链表长度int ListSize(LNode* L) { assert(L);//L是头结点 int size 0; LNode* cur L-next;//第一个有效节点 while (cur)//从第一个有效节点开始这样也是遍历有头结点单链表的代码 { size; cur cur-next; } return size; }这里涉及到一个遍历链表的循环cur是第一个有效节点0开始。5、打印链表//List.h void ListPrint(LNode* L) //List.c //打印链表 void ListPrint(LNode* L) { assert(L); LNode* cur L-next;//第一个有效节点,这里的L是哨兵位头结点数值域不放东西 while (cur) { printf(%d-,cur-data); cur cur-next; } printf(NULL\n); }6、查找元素根据数值查找//获取第一个节点为x的链表并返回其地址 LNode* ListLocateElem(LNode* L, LDataType x) { assert(L); LNode* cur L-next; while (cur)//遍历一个一个比较 { if (cur-data x) { return cur; } cur cur-next; } return NULL; }通过一个一个的比对查找根据下标查找//获取下标是i的节点并且返回其地址 LNode* ListGetElem(LNode* L, int i) { assert(L); assert(i 0); int j 0; LNode* iNode L-next; while (iNodeji) { j; iNode iNode-next; } return iNode; }7、插入根据下标插入//在下标为i的节点处插入一个节点 LNode* ListInsert(LNode* L, int i) { assert(L); assert(i 0); int j -1;//从头结点开始不然头插不了 LNode* i_1Node L; while (i_1Node j i-1) { i_1Node i_1Node-next; j; } assert(i_1Node);//先判断是否符合是空的 LNode* newNode BuyListNode(30);//再来创造新的节点如果顺序打乱可能创造了节点没有连接形成野指针 newNode-next i_1Node-next; i_1Node-next newNode; return newNode; }链表的插入很容易错因为进行头插的时候要从头结点开始遍历而不是从第一个有效节点开始不然覆盖不了所有节点。还有当插入链表的时候一定要先修改新节点的next,也就是从后面开始修改再将i_1Node的next和newNode进行连接防止找不到后面的节点。头插//头插,数值是x void ListPushFront(LNode* L, LDataType x) { assert(L); LNode* newNode BuyListNode(x); newNode-next L-next; L-nextnewNode; }尾插//尾插,数值是x void ListPushBack(LNode* L, LDataType x) { assert(L); LNode* newNode BuyListNode(x); newNode-next NULL; // 情况1空链表 if (L-next NULL) { L-next newNode; return; } // 情况2非空链表 LNode* cur L-next; while (cur-next ! NULL) { cur cur-next; } cur-next newNode; }这里要判断一下是否是空表8、删除根据下标删除//在下标为i的节点处删除一个节点,返回该节点处的值 LDataType ListDelete(LNode* L, int i) { assert(L); assert(i0); int j -1; LNode* i_1Node L; while (i_1Node j i-1 ) { i_1Node i_1Node-next; j; } assert(i_1Node i_1Node-next); LNode* iNode i_1Node-next; LDataType x iNode-data; i_1Node-next iNode-next; free(iNode); return x; }这里同理的要注意一下头指针在进行删除第一个有效节点的时候同样从头结点开始头删//头删并且返回删除的值 LDataType ListPopFront(LNode* L) { assert(L); assert(L-next); LNode* first L-next; LDataType x first-data; L-next first-next; free(first); first NULL; return x; }尾删//尾删,返回删除的值 LDataType ListPopBack(LNode* L) { assert(L); assert(L-next); LNode* prev L; LNode* cur L-next; while (cur-next) { prev cur; cur cur-next; } LDataType x cur-data; free(cur); prev-next NULL; return x; }9、销毁//销毁链表 void ListDestroy(LNode* L) { assert(L); LNode* cur L; while (cur) { LNode* next cur-next; free(cur); cur next; } }这里不用置空是因为是局部变量会销毁的。

相关推荐

如何用HS2-HF_Patch快速解锁Honey Select 2完整游戏体验:新手终极指南
如何用HS2-HF_Patch快速解锁Honey Select 2完整游戏体验:新手终极指南

如何用HS2-HF_Patch快速解锁Honey Select 2完整游戏体验:新手终极指南 【免费下载链接】HS2-HF_Patch Automatically translate, uncensor and update HoneySelect2! 项目地址: https://gitcode.com/gh_mirrors/hs/HS2-HF_Patch 你是否正在寻找一个能够彻底改… · 2026/9/22 10:11:06

为什么越来越多人开始用向量引擎 API 中转站?一篇讲清 token、接口、算力和 主流平台的深度测评
为什么越来越多人开始用向量引擎 API 中转站?一篇讲清 token、接口、算力和 主流平台的深度测评

如果你现在正在找一个向量引擎 API 中转站,最容易踩的坑不是“贵一点”,而是“看起来便宜,用起来却不稳”;不是“文档少一点”,而是“接进去之后发现限速、计费、权限、合规全都藏在细节里”。真正让人头疼的&#xff… · 2026/9/23 4:38:54

【山东大学项目实训FinAgent】FinAgent模拟交易(下):资产仪表盘、单股联动与风险提示
【山东大学项目实训FinAgent】FinAgent模拟交易(下):资产仪表盘、单股联动与风险提示

FinAgent模拟交易(下):资产仪表盘、单股联动与风险提示 摘要:在模拟交易账本与市价单(上篇)落地后,本文记录第二阶段至第四阶段的前后端实现:按日资产快照与ECharts仪表盘、与单股分… · 2026/9/22 22:00:15

异构动环平台接入:Modbus与SNMP协议转换选型与调试指南
异构动环平台接入:Modbus与SNMP协议转换选型与调试指南

机房、弱电间、库房改造这类项目里,最常被问到的就是“动环平台怎么接”。但真正动手做的时候卡住的往往不是平台本身,而是传感器和平台根本说不上话。这篇文章就围绕一个很典型的场景展开:现场有一批温湿度传感器,平台侧只愿意开… · 2026/9/24 23:04:01

审查网页元素实战指南:从DevTools入门到前端调试进阶
审查网页元素实战指南:从DevTools入门到前端调试进阶

做前端的年头久了,被问得最多的问题之一就是:老师,审查网页元素到底怎么用?每次听到这个问题我都想笑——因为在Chrome里,你只需要在页面上右键,点一下“检查”(老版本叫“审查元素”&#xff0… · 2026/9/24 23:04:01

Java多态从入门到精通:原理、实战与面试考点解析
Java多态从入门到精通:原理、实战与面试考点解析

"当爹的引用指向儿子,跑起来却是儿子的脾气"——这句话我经常用来给刚入门的同事解释Java多态。多态作为面向对象三大特性(封装、继承、多态)中最难讲清楚的一个,面试必问、工作必用,但真正能把它讲透的人不… · 2026/9/24 23:04:01

Servlet+JSP酒店管理系统课程设计:从环境搭建到答辩避坑全链路
Servlet+JSP酒店管理系统课程设计:从环境搭建到答辩避坑全链路

简介:这是一套面向计算机专业学生与Java Web初学者的酒店管理系统完整项目源码,采用servletjspmysqljquery技术栈,适合作为毕业设计、课程设计或Java Web入门练手项目。压缩包共15个文件,约186.16MB,包含sql数据库脚本… · 2026/9/24 23:04:01

Django+Python外卖配送分析与可视化系统毕业设计全解析
Django+Python外卖配送分析与可视化系统毕业设计全解析

每年到毕业季,总有一批学生围着外卖配送分析这类选题打转。为什么?因为外卖场景人人都用过,数据直观,可视化效果好,评委老师一听就懂,讲起来也有得说。而基于Django Python的这套外卖配送分析与可视化系统… · 2026/9/24 23:04:01

Modbus转MQTT网关:老旧设备数据上云的最短路径
Modbus转MQTT网关:老旧设备数据上云的最短路径

1. 先说清楚:那些"无通信接口"的老设备,卡在了哪一步1.1 没有网口不代表没有数据接口,多数设备藏着RS485干过现场改造的人应该都有这种经历:业主指着车间里一台用了快二十年的温控柜说,"这设备没有通信… · 2026/9/24 23:03:54

基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程
基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程

简介:这是一套面向计算机、人工智能、自动化等专业学生与教师的毕业设计级项目资源,围绕YOLOv8实现渔船作业监控系统,可用于毕设、课程设计、大作业或项目立项演示。压缩包共97个文件,约24.21MB,以70个Python源码文件为… · 2026/9/24 0:00:13

1D-CNN时间序列建模实战:从Conv1d原理到工业落地
1D-CNN时间序列建模实战:从Conv1d原理到工业落地

简介:面向时间序列数据建模的一维卷积神经网络完整实现,适合深度学习入门者及需要快速验证时序模型的研究者,能够从音频、文本、传感器或股价等序列中挖掘局部特征与时间依赖。压缩包体积很小,只有3KB,内含3个Python脚… · 2026/9/24 0:00:26

柔软的L:汉语语流中被忽视的舌肌张力控制
柔软的L:汉语语流中被忽视的舌肌张力控制

1. 这个“L”不是字母表里的L,而是舌尖上的L最近在几个方言群和语音教学社群里,反复看到有人发一句:“也说字母L:柔软的长舌”。初看以为是英语发音课笔记,点开才发现全是方言爱好者、播音系学生、语言康复师甚至戏曲演… · 2026/9/24 0:00:44

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码