单链表数据结构详解
创作时间:
作者:
@小白创作中心
单链表数据结构详解
引用
CSDN
1.
https://m.blog.csdn.net/2402_86681376/article/details/145459721
一、链表的概念
链表是一种物理存储结构上非连续、非顺序的存储结构,链表由一个个节点(node)组成,数据结构的逻辑顺序是通过链表中的指针链接次序实现的。
链表的节点通常是一个结构体变量,每一个节点都是独立的空间,它们在内存中的地址不一定是连续的。而把它们串联在一起的便是结构体中的指针。第一个节点的指针成员指向第二个节点,第二个节点的指针成员指向第三个节点……最后一个节点的指针成员是空指针:
struct SListNode
{
int data; //存储的数据
struct SListNode* next; //指针变量用于保存下一个节点的地址
};
也就是说,链表是一种逻辑上线性,物理(地址)上非线性的数据结构。链表也包括很多种,如单链表、双向链表等等,今天我们学习单链表。
二、单链表
1. 结构
顾名思义,单链表就是单向的链表,节点之间是单向指向的:
每一个节点的结构是:
typedef struct SListNode
{
SLTDataType data;
struct SListNode* next;
}SLTNode;
一般来说,节点是一个一个申请的,初始化时也需要一个一个来
2. 创建一个单链表并初始化
SLTNode* node1 = (SLTNode*)malloc(sizeof(SLTNode));
SLTNode* node2 = (SLTNode*)malloc(sizeof(SLTNode));
SLTNode* node3 = (SLTNode*)malloc(sizeof(SLTNode));
SLTNode* node4 = (SLTNode*)malloc(sizeof(SLTNode));
node1->data = 11;
node2->data = 22;
node3->data = 33;
node4->data = 44;
node1->next = node2;
node2->next = node3;
node3->next = node4;
node4->next = NULL;
SLTNode* plist = node1;
像这样,一个单链表的雏形就出现了,plist是它的首节点地址。后续对单链表进行修改时,要利用plist。下面的功能,都用函数来实现,涉及修改链表的函数要传递plist的地址,即二级指针。
3. 申请一个新节点
在往链表插入一个新数据x前,我们首先要向操作系统申请一个节点用来存储这个数据x,节点的指针成员先置为NULL,返回申请好的新节点的地址。
SLTNode* SLTBuyNode(SLTDataType x)
{
SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));
if (newnode == NULL)
{
perror("malloc fail!");
exit(1); //申请空间失败则返回1
}
newnode->data = x;
newnode->next = NULL;
return newnode;
}
4. 尾部插入数据
这个函数有两个参数:指向链表首节点的指针的地址、要插入的新数据。
void SLTPushBack(SLTNode** pphead, SLTDataType x)
{
assert(pphead);
SLTNode* newnode = SLTBuyNode(x);
if (*pphead == NULL) //若链表为空,则phead直接指向newnode节点
{
*pphead = newnode;
}
else //链表不为空,则找到尾结点,将尾结点和newnode节点连接起来
{
SLTNode* ptail = *pphead;
while (ptail->next != NULL)
{
ptail = ptail->next;
}
ptail->next = newnode;
}
}
5. 头部插入数据
头部插入数据,要让新节点的指针成员指向原来的第一个节点,新节点成为链表的第一个节点
void SLTPushFront(SLTNode** pphead, SLTDataType x)
{
assert(pphead);
SLTNode* newnode = SLTBuyNode(x);
newnode->next = *pphead;
*pphead = newnode;
}
6. 尾部删除数据
void SLTPopBack(SLTNode** pphead)
{
assert(pphead && *pphead); //若*pphead为空,则链表为空,无节点可删
if ((*pphead)->next == NULL) //若链表只有一个节点,则free后置为NULL
{
free(*pphead);
*pphead = NULL;
}
else //若链表不止一个节点,则找尾节点。尾结点的前一个节点的指针成员置为NULL,尾结点free后置为NULL
{
SLTNode* prev = NULL;
SLTNode* ptail = *pphead;
while (ptail->next != NULL)
{
prev = ptail;
ptail = ptail->next;
}
prev->next = NULL;
free(ptail);
ptail = NULL;
}
}
7. 头部删除数据
先将首节点的指针成员保存在next中,将首节点free掉后,next就是首节点地址了。
void SLTPopFront(SLTNode** pphead)
{
assert(pphead && *pphead);
SLTNode* next = (*pphead)->next;
free(*pphead);
*pphead = next;
}
8. 指定节点之前插入数据
void SLTInsertBefore(SLTNode** pphead, SLTNode* pos, SLTDataType x)
{
assert(pphead && pos);
if (*pphead == pos) //如果pos就是首节点,则直接执行刚才的头部插入数据函数
{
SLTPushFront(pphead, x);
}
else //如果pos不是首节点,先找pos节点,将新节点插入到pos和pos前一个节点之间
{
SLTNode* newnode = SLTBuyNode(x);
SLTNode* prev = *pphead;
while (prev->next != pos)
{
prev = prev->next;
}
newnode->next = pos;
prev->next = newnode;
}
}
9. 指定节点之后插入数据
上一条在指定节点之前插入数据,由于要找pos的上一个节点,因此还要传参首节点。而这一条在指定节点之后插入数据,pos节点自己就能找到下一个节点,就不需要传参首节点了。
void SLTInsertAfter(SLTNode* pos, SLTDataType x)
{
assert(pos);
SLTNode* newnode = SLTBuyNode(x);
newnode->next = pos->next;
pos->next = newnode;
}
10. 删除指定节点
void SLTErase(SLTNode** pphead, SLTNode* pos)
{
assert(pphead && pos);
if (*pphead == pos) //若pos就是首节点,则执行头部删除数据操作
{
SLTPopFront(pphead);
}
else //若pos不是首节点,则找pos的前一个节点,将pos的前后连接起来,pos节点free后置为NULL
{
SLTNode* prev = *pphead;
while (prev->next != pos)
{
prev = prev->next;
}
prev->next = pos->next;
free(pos);
pos = NULL;
}
}
11. 删除指定位置之后的节点
void SLTEraseAfter(SLTNode* pos)
{
assert(pos && pos->next);
SLTNode* del = pos->next;
pos->next = del->next;
free(del);
del = NULL;
}
12. 销毁链表
遍历整个链表,将每个节点free,最后将首节点置为NULL
void SLTDestory(SLTNode** pphead)
{
assert(pphead);
SLTNode* pcur = *pphead;
while (pcur != NULL)
{
SLTNode* next = pcur->next;
free(pcur);
pcur = next;
}
*pphead = NULL;
}
以上就是单链表及其基础操作
本篇完,感谢阅读
热门推荐
珠峰登顶人数破万,环境污染问题日益严峻
空腹吃苹果的五大健康益处:营养专家详解其科学依据
广州重启春节烟花汇演,白鹅潭上演45分钟视觉盛宴
他们的“墓志铭”书写着千年前火焰山脚下的卫戍故事
秋冬养生首选茶树菇:高蛋白低脂肪,这样挑选储存最保鲜
《送你一束沙枣花》:兵团人的青春之歌
茶树菇抗癌功效获科学背书,同时兼具多重健康效益
茶树菇食用全攻略:8大安全指南+2种创新烹饪法
“中华神菇”富硒茶树菇:18种氨基酸助力秋冬养生
“中华神菇”茶树菇:高蛋白低脂肪,六重功效护健康
心梗后怎么吃?专家详解饮食禁忌与营养方案
海马体:记忆存储的秘密基地
福特野马驾驶技巧全攻略:从启动到驰骋
心梗后怎么吃?八大饮食建议助力康复
心梗后如何吃?医生推荐这份饮食管理指南
北京师范大学揭秘记忆奥秘:神经活动重放如何塑造我们的记忆
神经元DNA修复揭秘记忆形成奥秘
医院CT等收费将执行新规
成都双机场暑运交出亮眼成绩单:旅客吞吐量增14.7%
北京机场大盘点:4座军用2座民用,新机场将成全球最大
双流航空产业破千亿:空客顺丰双引擎驱动,打造西部临空经济新高地
踝泵练习:中老年人的血栓克星
经济舱综合征:长途飞行如何预防致命血栓?
中医养生:穴位按摩与红色食物助力预防血栓
冬青补汁使用指南:这些注意事项要记牢
轻度肺气肿患者的冬季养生指南
蓝莓:肺气肿患者的营养新选择
冬季肺气肿患者的心理调适秘籍
2025年春节档影视作品大盘点:从《哪吒》到《封神》,这些作品最值得期待!
什么是握寿司(Nigiri)?