C语言链表有什么用
发表于:2025-11-16 作者:千家信息网编辑
千家信息网最后更新 2025年11月16日,这篇文章将为大家详细讲解有关C语言链表有什么用,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。链表的概念及结构概念链表是一种物理存储结构上非连续、非顺序的存储结构,数
千家信息网最后更新 2025年11月16日C语言链表有什么用
这篇文章将为大家详细讲解有关C语言链表有什么用,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。
链表的概念及结构
概念
链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的 。
结构
代码
struct Slist{ int* a; struct Slist* next;};逻辑结构:
物理结构:
注意:
从上图可以看出,链式结构在逻辑上是连续的,但是在物理上是不一定是连续的。
这些结点一般是从堆上申请出来的。
从堆上申请的空间,是按照一定的策划来分配的,两次申请的空间可能连续,大概率是不连续的。
链表的分类
实际中链表的结构非常多样,以下情况组合起来就有8种链表结构:
1. 单向或者双向
①单向

②双向
2.带头或者不带头
①带头

②不带头
3.循环或者非循环
①循环
②非循环
虽然有这么多种结构的链表,但是我们实际中最常用的只有两种结构:
1. 无头单向非循环链表
2.带头双向循环链表
1. 无头单向非循环链表:结构简单,一般不会单独用来存数据。实际中更多是作为其他数据结构的子结构,如哈希桶、图的邻接表等等。另外这种结构在笔试面试中出现很多。
2. 带头双向循环链表:结构最复杂,一般用在单独存储数据。实际中使用的链表数据结构,都是带头双向循环链表。另外这个结构虽然结构复杂,但是使用代码实现以后会发现结构会带来很多优势,实现反而简单了,后面我们代码实现了就知道了。
单链表的实现(无头)
单链表结构
typedef int SLTDateType;typedef struct SListNode{ SLTDateType data; struct SListNode* next;}SListNode;单链表需要的功能
// 动态申请一个节点SListNode* BuySListNode(SLTDateType x);// 单链表打印void SListPrint(SListNode* plist);// 单链表尾插void SListPushBack(SListNode** pplist, SLTDateType x);// 单链表的头插void SListPushFront(SListNode** pplist, SLTDateType x);// 单链表的尾删void SListPopBack(SListNode** pplist);// 单链表头删void SListPopFront(SListNode** pplist);// 单链表查找SListNode* SListFind(SListNode* plist, SLTDateType x);// 单链表在pos位置之后插入x// 分析思考为什么不在pos位置之前插入?void SListInsertAfter(SListNode* pos, SLTDateType x);// 单链表删除pos位置之后的值// 分析思考为什么不删除pos位置?void SListEraseAfter(SListNode* pos);// 单链表的销毁void SListDestory(SListNode** pplist);
功能实现
SListNode* BuySListNode(SLTDateType x){ SListNode* newnode = (SListNode*)malloc(sizeof(SListNode)); if (newnode == NULL) { exit(-1); } newnode->data = x; return newnode;}void SListPrint(SListNode* plist){ if (plist == NULL) { printf("NULL\n"); return; } else { while (plist) { printf("%d->", plist->data); plist = plist->next; } printf("NULL\n"); }}void SListPushBack(SListNode** pplist, SLTDateType x){ SListNode* tail = *pplist; SListNode* newnode = BuySListNode(x); newnode->next = NULL; if (tail == NULL) { *pplist = newnode; } else { while (tail->next) { tail = tail->next; } tail->next = newnode; }}void SListPushFront(SListNode** pplist, SLTDateType x){ SListNode* newnode = BuySListNode(x); newnode->next = *pplist; *pplist = newnode;}void SListPopBack(SListNode** pplist){ assert(*pplist); SListNode* tail = *pplist; SListNode* Pretail = NULL; if (tail->next == NULL) { *pplist = NULL; return; } else { while (tail->next) { Pretail = tail; tail = tail->next; } free(tail); tail = NULL; Pretail->next = NULL; }}void SListPopFront(SListNode** pplist){ assert(*pplist); SListNode* front = *pplist; *pplist = front->next; free(front); front = NULL;}SListNode* SListFind(SListNode* plist, SLTDateType x){ assert(plist); SListNode* pos = plist; while (pos && pos->data != x) { pos = pos->next; } return pos;}void SListInsertAfter(SListNode* pos, SLTDateType x){ assert(pos); SListNode* newnode = BuySListNode(x); newnode->next = pos->next; pos->next = newnode;}void SListEraseAfter(SListNode* pos){ assert(pos); assert(pos->next); SListNode* node = pos->next; pos->next = node->next; free(node);}void SListDestory(SListNode** pplist){ SListNode* node = *pplist; SListNode* PreNode = NULL; while (node) { PreNode = node->next; free(node); node = PreNode; }}双向链表的实现
双向链表的结构
SListNode* BuySListNode(SLTDateType x){ SListNode* newnode = (SListNode*)malloc(sizeof(SListNode)); if (newnode == NULL) { exit(-1); } newnode->data = x; return newnode;}void SListPrint(SListNode* plist){ if (plist == NULL) { printf("NULL\n"); return; } else { while (plist) { printf("%d->", plist->data); plist = plist->next; } printf("NULL\n"); }}void SListPushBack(SListNode** pplist, SLTDateType x){ SListNode* tail = *pplist; SListNode* newnode = BuySListNode(x); newnode->next = NULL; if (tail == NULL) { *pplist = newnode; } else { while (tail->next) { tail = tail->next; } tail->next = newnode; }}void SListPushFront(SListNode** pplist, SLTDateType x){ SListNode* newnode = BuySListNode(x); newnode->next = *pplist; *pplist = newnode;}void SListPopBack(SListNode** pplist){ assert(*pplist); SListNode* tail = *pplist; SListNode* Pretail = NULL; if (tail->next == NULL) { *pplist = NULL; return; } else { while (tail->next) { Pretail = tail; tail = tail->next; } free(tail); tail = NULL; Pretail->next = NULL; }}void SListPopFront(SListNode** pplist){ assert(*pplist); SListNode* front = *pplist; *pplist = front->next; free(front); front = NULL;}SListNode* SListFind(SListNode* plist, SLTDateType x){ assert(plist); SListNode* pos = plist; while (pos && pos->data != x) { pos = pos->next; } return pos;}void SListInsertAfter(SListNode* pos, SLTDateType x){ assert(pos); SListNode* newnode = BuySListNode(x); newnode->next = pos->next; pos->next = newnode;}void SListEraseAfter(SListNode* pos){ assert(pos); assert(pos->next); SListNode* node = pos->next; pos->next = node->next; free(node);}void SListDestory(SListNode** pplist){ SListNode* node = *pplist; SListNode* PreNode = NULL; while (node) { PreNode = node->next; free(node); node = PreNode; }}双向链表的功能
//创建链表返回头结点LTNode* ListInit();// 双向链表销毁void ListDestory(LTNode* phead);// 双向链表打印void ListPrint(LTNode* phead);// 双向链表尾插void ListPushBack(LTNode* phead, LTDateType x);// 双向链表尾删void ListPopBack(LTNode* phead);// 双向链表头插void ListPushFront(LTNode* phead, LTDateType x);// 双向链表头删void ListPopFront(LTNode* phead);// 双向链表查找LTNode* ListFind(LTNode* phead, LTDateType x);// 双向链表在pos的前面进行插入void ListInsert(LTNode* pos, LTDateType x);// 双向链表删除pos位置的节点void ListErase(LTNode* pos);
功能实现
LTNode* ListInit(){ //哨兵位头结点 LTNode* phead = (LTNode*)malloc(sizeof(LTNode)); if (phead == NULL) { printf("开辟空间失败!!!\n"); exit(-1); } phead->next = phead; phead->prev = phead; return phead;}void ListDestory(LTNode* phead){ assert(phead); LTNode* cur = phead; LTNode* p = NULL; LTNode* tail = phead->prev; while (cur != tail) { p = cur; cur = cur->next; free(p); } free(tail);}void ListPrint(LTNode* phead){ assert(phead); LTNode* front = phead->next; while (front != phead) { printf("%d ", front->data); front = front->next; } printf("\n");}void ListPushBack(LTNode* phead, LTDateType x){ assert(phead); LTNode* tail = phead->prev; LTNode* newnode = (LTNode*)malloc(sizeof(LTNode)); if (newnode == NULL) { printf("开辟空间失败!!\n"); exit(-1); } newnode->data = x; tail->next = newnode; newnode->prev = tail; newnode->next = phead; phead->prev = newnode;}void ListPopBack(LTNode* phead){ assert(phead); assert(phead != phead->next); LTNode* tail = phead->prev; LTNode* TailFront = tail->prev; TailFront->next = phead; phead->prev = TailFront; free(tail);}void ListPushFront(LTNode* phead, LTDateType x){ assert(phead); LTNode* next = phead->next; LTNode* newnode = (LTNode*)malloc(sizeof(LTNode)); if (newnode == NULL) { printf("开辟空间失败!!\n"); exit(-1); } newnode->data = x; phead->next = newnode; newnode->prev = phead; newnode->next = next; next->prev = newnode;}void ListPopFront(LTNode* phead){ assert(phead); assert(phead != phead->next); LTNode* head = phead->next;//头结点 phead->next = head->next; head->next->prev = phead; free(head);}LTNode* ListFind(LTNode* phead, LTDateType x){ assert(phead); LTNode* cur = phead->next; while (cur != phead) { if (cur->data == x) { return cur; } cur = cur->next; } return NULL;}void ListInsert(LTNode* pos, LTDateType x){ assert(pos); LTNode* posPrev = pos->prev; LTNode* newnode = (LTNode*)malloc(sizeof(LTNode)); if (newnode == NULL) { printf("开辟空间失败!!\n"); exit(-1); } newnode->data = x; posPrev->next = newnode; newnode->prev = posPrev; newnode->next = pos; pos->prev = newnode;}void ListErase(LTNode* pos){ assert(pos); LTNode* posPrev = pos->prev; LTNode* posNext = pos->next; posPrev->next = posNext; posNext->prev = posPrev; free(pos);}关于"C语言链表有什么用"这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。
结构
双向
空间
位置
数据
环链
功能
单向
实际
结点
循环
代码
更多
物理
篇文章
表头
逻辑
无头
存储
语言
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
为什么无法联结服务器
张店轻工业软件开发价格
识别图片软件开发
服务好的oa办公软件开发定制
外文文献用哪个数据库比较好
数据库软件使用视频教程
该机不在服务器管理
数据库开发在榆次好就业吗
管理层网络安全意识培训
网络安全信息通报领导小组
计算机先学计算机网络安全
去制造业的软件开发
如何控制软件开发质量
如何对服务器进行压力测试
镜像管理服务器
域名服务器的dns是什么
软件开发需要什么技术
剑昆互联网络科技有限公司临桂
经济管理学科数据库
求生之路2怎么看服务器地区
学网络技术的学校
b站数据库起火
数据库中 业务计算
3d仿真模拟软件开发工具
四川服务器维修价格
ensp如何把服务器映射到外网
网络安全行业存在的威胁
熟悉数据库的用途
苹果电脑 代理服务器
青藤云网络安全交付师面试