尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
单链表从入门到实战:概念、结构与 C 语言接口实现全解析
目录1. 链表的定义1.1 什么是链表1.2 什么是节点1.3 节点的结构体代码1.4 节点和链表的关系2. 链表的性质3. 链表的优势4. 链表的打印5. 单链表5.1 申请节点5.2 链表尾插5.3 链表头插5.4 链表头删5.5 链表尾删5.6 在指定位置前插入5.7 在指定位置后插入5.8 指定位置删除5.9 查找元素5.10 打印元素5.11 销毁链表6. 总结1.1 什么是链表链表是一种在物理存储上节点分散、不连续的存储数据的结构其逻辑顺序由链表中的指针依次链接而成。与数组需要一整块连续内存不同链表的每个节点可以散落在内存的任意位置节点之间靠指针建立联系。既然如此那么什么是节点呢1.2 什么是节点节点的构成数据区域 指针区域。数据区域用来存放实际的数据指针区域用来存放下一个节点的地址。如上图所示上半部分是数据区域用于存放节点数据例如数据 1下半部分存放地址例如地址 0x0012FFA0。两者共同构成了一个节点。1.3 节点的结构体代码假设当前保存的节点数据是整型typedefintSLTDataType;typedefstructSListNode{SLTDataType data;// 节点数据structSListNode*next;// 保存下一个节点的地址}SLTNode;1.4 节点和链表的关系节点是组成链表的基本单元链表则是节点通过指针串联起来的整体。二者的关系就如同火车与车厢车厢相当于节点车厢组成了火车而节点组成了链表。需要特别注意的是第一个节点中存放的是第二个节点的地址第二个节点指向第三个节点的地址以此类推最后一个节点存放的是空指针。2. 链表的性质链式结构在逻辑上是连续的在物理上不一定连续。节点一般是从堆上申请的。从堆上申请来的空间按照一定策略分配每次申请的空间可能连续也可能不连续。3. 链表的优势动态分配内存不需要预先确定大小按需分配节点不容易造成空间浪费。任意位置插入、删除效率高。内存不要求连续节点分散在堆内存中无需寻找一整块连续的大空间。4. 链表的打印voidSLTPrint(SLTNode*phead){SLTNode*pcurphead;while(pcur){printf(%d,pcur-data);pcurpcur-next;}printf(\n);}解释SLTSingle Linked List单链表node节点SLTPrint打印单链表的接口函数phead头指针保存链表第一个节点的地址SLTNode单链表节点的类型名pcur当前指针5. 单链表单链表只能从头节点向尾部单向遍历无法直接反向访问前驱节点。也正因为如此单链表的结构简单、实现方便是学习链表时最先接触的一种形式后续的双向链表、循环链表都是在它的基础上扩展而来的。5.1 申请节点SLTNode*SLBuyNode(SLTDataType x){SLTNode*node(SLTNode*)malloc(sizeof(SLTNode));node-datax;node-nextNULL;returnnode;}5.2 链表尾插voidpushback(SLTNode**pphead,SLTDataType x){assert(pphead);SLTNode*nodeSLBuyNode(x);//申请新节点if(*ppheadNULL)//如果链表为空{*ppheadnode;return;}//链表不为空寻找尾节点并在其后插入新节点SLTNode*pcur*pphead;while(pcur-next!NULL){pcurpcur-next;}pcur-nextnode;}5.3 链表头插voidSLPushFront(SLTNode**pphead,SLTDataType x){assert(pphead);SLTNode*nodeSLBuyNode(x);//创建新节点node-next*pphead;//新节点指向原来第一个节点*ppheadnode;//新节点变为头指针}5.4 链表头删voidSLPopFront(SLTNode**pphead){assert(pphead);assert(*pphead);//如果链表为空就没有节点可以删SLTNode*del*pphead;//将第一个节点保存在del中*ppheaddel-next;//将第二个节点作为首节点//释放头节点并置为空指针free(del);delNULL;}5.5 链表尾删voidSLPopBack(SLTNode**pphead){assert(pphead);assert(*pphead);if((*pphead)-nextNULL)//链表只有一个节点的情况{free(*pphead);*ppheadNULL;return;}SLTNode*prevNULL;SLTNode*ptail*pphead;//初始条件prev为空指针ptail在头节点while(ptail-next!NULL){prevptail;ptailptail-next;}prev-nextptail-next;//使prev下一节点为空free(ptail);ptailNULL;}5.6 在指定位置前插入voidSLInsert(SLNode**pphead,SLNode*pos,SLDataType x){assert(pos);assert(pphead);if(pos*pphead){SLPushFront(pphead,x);}else{SLNode*prev*pphead;while(prev-next!pos){prevprev-next;}SLNode*newnodeSLBuyNode(x);newnode-nextpos;prev-nextnewnode;}}5.7 在指定位置后插入//使用这个函数要搭配SLFind这个函数voidSLInsertAfter(SLNode*pos,SLDataType x){assert(pos);SLNode*newnodeBuySLNode(x);newnode-nextpos-next;pos-nextnewnode;}5.8 指定位置删除voidSLErase(SLTNode**pphead,SLTNode*pos){assert(pos);//确保删除的节点是有效的assert(pphead);if(*ppheadpos){SLPopFront(pphead);}else{SLTNode*prev*pphead;while(prev-next!pos)//寻找该位置的前一个节点{prevprev-next;}prev-nextpos-next;//进行删除操作free(pos);//释放节点内存}}5.9 查找元素SLTNode*SLFind(SLTNode*phead,SLTDataType x){SLTNode*curphead;//创建遍历指针从头节点开始遍历while(cur){if(cur-datax){returncur;}curcur-next;}returnNULL;//循环走完都没找到x返回空指针表示查找失败}5.10 打印元素voidSLPrint(SLNode*phead){SLNode*headphead;//新建临时遍历指针head将头指针赋值给它while(head){printf(%d-,head-data);//打印head里面存的数据headhead-next;}printf(NULL\n);//循环结束后打印NULL}5.11 销毁链表voidSLDestroy(SLNode**pphead){assert(pphead);assert(*pphead);SLNode*cur*pphead;while(cur!NULL){SLNode*nextcur-next;//保存下一个节点的位置free(cur);//释放当前节点curnext;//移动到下一个节点}*ppheadNULL;}6. 总结本文从最基础的概念出发完整梳理了单链表的知识体系可以归纳为以下几个要点概念层面链表是一种物理存储上不连续、逻辑上连续的数据结构由一个个节点通过指针串联而成。节点由数据区域和指针区域两部分组成前者存放实际数据后者存放下一个节点的地址。性质与优势链式结构逻辑连续、物理不一定连续节点通常从堆上申请相比数组链表支持动态分配内存、任意位置插入删除效率高且不要求内存连续。接口实现围绕单链表我们依次实现了申请节点、尾插、头插、头删、尾删、指定位置前插入、指定位置后插入、指定位置删除、查找元素、打印元素以及销毁链表等核心操作。这些接口基本覆盖了单链表的日常使用场景。实现要点涉及头指针修改的操作如头插、头删、尾插空链表需要传入二级指针SLNode**pphead删除节点后要及时free并置空避免野指针遍历时注意边界条件尤其是空链表和只有一个节点的情形。单链表是学习更复杂链式结构的基础掌握它的增删查改逻辑后再学习双向链表、循环链表乃至栈和队列的链式实现都会更加得心应手。建议读者亲手把上述代码敲一遍并尝试补充测试用例加深对指针操作的理解。
RELATED

相关推荐

NSG与VNet Peering深度指南:DevOps Insiders Batch 18控制跨虚拟网络访问的完整方法

NSG与VNet Peering深度指南:DevOps Insiders Batch 18控制跨虚拟网络访问的完整方法

【免费下载链接】azure-aws-gcp-devsecops-mlops-batch-18 Welcome to the official repository for Batch18! 📚👩‍💻 Here, youll find a organized collection of class notes, assignments, and code snippets generated during our ses…

📅 2026/11/1 1:50:44
BrowserSkill bsk update 升级指南:daemon 重启的 3 条路径、Windows 分阶段替换与升级后 30 秒验证

BrowserSkill bsk update 升级指南:daemon 重启的 3 条路径、Windows 分阶段替换与升级后 30 秒验证

BrowserSkill bsk update 升级指南:daemon 重启的 3 条路径、Windows 分阶段替换与升级后 30 秒验证 【免费下载链接】BrowserSkill Let AI agents use your real, logged-in browser without interrupting your work. CLI extension for browser automation acros…

📅 2026/11/1 1:50:44
Jasna 马赛克修复选型手册:6 个检测模型与 3 个阈值,新手 3 分钟快速定稿

Jasna 马赛克修复选型手册:6 个检测模型与 3 个阈值,新手 3 分钟快速定稿

Jasna 马赛克修复选型手册:6 个检测模型与 3 个阈值,新手 3 分钟快速定稿 【免费下载链接】jasna Video restoration tool 项目地址: https://gitcode.com/GitHub_Trending/ja/jasna Jasna 是一款开源的视频马赛克修复工具:检测模型先…

📅 2026/11/1 1:50:44
MORE NEWS

更多资讯

📰

启动报Port 8088 was already in use?先查是谁占的

启动报Port 8088 was already in use?先查是谁占的 项目启动报 Port 8088 was already in use,意思很直白:这个端口已经有人占了。 先说原理:端口是"门牌号",一间房只住一个进程 端口就是一台机器上的门牌号…

📰

担心文档上云?本地运行的办公AI才敢放心用

单位上周开了个会,主题是"AI 提效",散会时领导补了一句:涉及客户资料的文档,不许往云端传。这话一出,会议室里本来跃跃欲试的同事全蔫了——大家平时用的那些在线 AI,文档一上传就不知道存哪儿去…

📰

先能用,再好用:从烂尾复盘到两周上线,全栈项目的‘原型—快速迭代‘方法论

先能用,再好用:从烂尾复盘到两周上线,全栈项目的“原型—快速迭代”方法论 全栈学习路径的文章已经很多了:怎么选技术栈、怎么搭环境、怎么记文档,几乎每个方向都有人写。但一个更扎心的问题很少有人正面讨论——为什…

📰

深度思考模式把 ARC-AGI-2 从 17.6% 拉到 45.1%:对照 Gemini 3 Pro 的三份能力评测,看‘会思考‘改写了哪些边界

深度思考模式把 ARC-AGI-2 从 17.6% 拉到 45.1%:对照 Gemini 3 Pro 的三份能力评测,看“会思考”改写了哪些边界 一、先说结论:变强的不是“知识”,而是“解法” 每次新模型发布,评测榜单都会涨几个点,大…

📰

1.c++入门篇

1.c中的关键字asmdoifreturntrycontinueautodoubleinlineshorttypedefforbooldynamic_castintsignedtypeidpublicbreakelselongsizeoftypenamethrowcaseenummutablestaticunionwchar_tcatchexplicitnamespacestatic_castunsigneddefaultcharexportnewstructusingfriendclassext…

📰

《江灯合声》:有可行的分框版,也仍可以选择连续鸣谢

武汉江岸区栎坡合唱团在免费节目册《江灯合声》中,以表格集中鸣谢资助者。各家共同要求改为独立小框,团里仍想保留表格。现有全名与支持事项清楚可见,双方此前未承诺具体排版。我支持保留表格。补充的试排材料让选择更具体:分框能…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬