C语言链表有什么用
发表于:2024-11-29 作者:千家信息网编辑
千家信息网最后更新 2024年11月29日,这篇文章将为大家详细讲解有关C语言链表有什么用,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。链表的概念及结构概念链表是一种物理存储结构上非连续、非顺序的存储结构,数
千家信息网最后更新 2024年11月29日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安全错误
数据库的锁怎样保障安全
鞍山纺织软件开发
arm工控主板 网络安全
萤石云云服务器在哪里
my软件开发者
服务器怎么运行excel
pppoe服务器配置实例
服务器怎么评价
cDN加速服务器那里好最好
网络安全宣传周采访发言
赌博软件开发需要多少钱
数据库原理及安全实验报告
越凡网络技术
网络安全公益视频手语
富阳软件开发者
shopex数据库表结构
玻璃砖贴图软件开发
网络安全专业的应用
铁岭im即时通讯软件开发
软件开发和ui设计哪个好用
夹江县名扬网络技术服务部
涉密总体集成资质包含软件开发
海尔电视代理服务器
CSDN数据库技术入股
软件开发模式调试模式生产模式
什么是中间层服务器
固话报错服务器回应报错
海南鹰海网络技术有限公司
NXP微控制器软件开发
违反网络安全法啥处罚
网络技术购销合同